【发布时间】:2026-01-11 01:35:01
【问题描述】:
我在 R 工作。我有一个 COVID 病例总数数据集,如下所示:
| Facility | Day_1 | Day_2 | Day_3 |
|---|---|---|---|
| A | 0 | 0 | 1 |
| B | 1 | 2 | 5 |
| C | 0 | 2 | 6 |
| D | 0 | 0 | 0 |
我想使用 mutate() 创建一个新列 first_case,它具有每行中第一个非零元素的列索引 - 如果没有非零元素,则为“NA”。我考虑过使用 where(),但不太清楚如何获取列索引而不是行索引。
非常感谢任何帮助!
【问题讨论】:
我在 R 工作。我有一个 COVID 病例总数数据集,如下所示:
| Facility | Day_1 | Day_2 | Day_3 |
|---|---|---|---|
| A | 0 | 0 | 1 |
| B | 1 | 2 | 5 |
| C | 0 | 2 | 6 |
| D | 0 | 0 | 0 |
我想使用 mutate() 创建一个新列 first_case,它具有每行中第一个非零元素的列索引 - 如果没有非零元素,则为“NA”。我考虑过使用 where(),但不太清楚如何获取列索引而不是行索引。
非常感谢任何帮助!
【问题讨论】:
我们可以使用max.col 来获取每个零值都非零时的第一个实例。
library(dplyr)
df %>%
mutate(first_case = {
tmp <- select(., starts_with('Day'))
ifelse(rowSums(tmp) == 0, NA, max.col(tmp != 0, ties.method = 'first'))
})
# Facility Day_1 Day_2 Day_3 first_case
#1 A 0 0 1 3
#2 B 1 2 5 1
#3 C 0 2 6 2
#4 D 0 0 0 NA
first_case 有'Day' 列的列号,如果您需要数据中的列号,您可以在上面的输出中添加+ 1。
【讨论】:
这可能是不必要的复杂,因为数据不是 dplyr 等期望的长(“整齐”)格式。
datlong <- dat %>%
pivot_longer(cols=starts_with("Day"), names_to = c("day"), names_pattern="_(\\d+)")
## A tibble: 12 x 3
# Facility day value
# <chr> <chr> <int>
# 1 A 1 0
# 2 A 2 0
# 3 A 3 1
# 4 B 1 1
# 5 B 2 2
# 6 B 3 5
# 7 C 1 0
# 8 C 2 2
# 9 C 3 6
#10 D 1 0
#11 D 2 0
#12 D 3 0
然后很容易让第一天/第二天/第三天/[n]天高于任何值,以及计算最小值、最大值、平均值、周平均值、滚动平均值等等,因为您现在正在处理普通的旧值向量,而不是跨多列的值列表。
datlong %>%
group_by(Facility) %>%
filter(value > 0, .preserve=TRUE) %>%
summarise(first_day = first(day))
#`summarise()` ungrouping output (override with `.groups` argument)
## A tibble: 4 x 2
# Facility first_day
# <chr> <chr>
#1 A 3
#2 B 1
#3 C 2
#4 D <NA>
使用索引和其他东西的替代方法,不像 dplyr-like:
datlong %>%
group_by(Facility) %>%
summarise(first_day = day[value > 0][1])
【讨论】: