我在R中有一个数据表,看起来像:
city year target
1: NYC 2000 0
2: NYC 2000 1
3: NYC 2000 1
4: LA 2000 0
5: LA 2000 0
6: LA 2000 1
7: LA 2000 1
可以通过以下方式创建:
data = data.table(city = c("NYC", "NYC", "NYC", "LA", "LA", "LA", "LA"),
year = c(2000, 2000, 2000, 2000, 2000, 2000, 2000),
target = c(0, 1, 1, 0, 0, 1, 1))
我想按city
和year
对它们进行分组,并在列target
中查找第一个非零元素的索引,以便我可以对其进行修改,期望的结果应如下所示:< / p>
city year target
1: NYC 2000 0
2: NYC 2000 666
3: NYC 2000 1
4: LA 2000 0
5: LA 2000 0
6: LA 2000 666
7: LA 2000 1
感谢您的帮助。
以下内容无效:
cutoff_thresh <- function(x, cutoff) {x > cutoff}
helper <- data %>%
group_by(city, year) %>%
mutate(thresh = detect_index(.x = target,
.f = cutoff_thresh,
cutoff = 0)
)
它会产生给定年份中第一个非零元素出现的确切日期,
它开始于每年的第一天。因此,如果2000年有365天,而2001年的第二天我们不为零,则它返回2
的{{1}}而不是(NYC, 2001)
。不足为奇!
答案 0 :(得分:3)
由于数据集已经是data.table
,因此使用data.table
方法可能更有效。按“城市”,“年”分组,获取第一个非零元素('i1')的行索引(.I
),在i
中使用它并分配(:=
) “目标”的值为666
library(data.table)
i1 <- data[, .I[target != 0][1], .(city, year)]$V1
data[i1, target := 666][]
# city year target
#1: NYC 2000 0
#2: NYC 2000 666
#3: NYC 2000 1
#4: LA 2000 0
#5: LA 2000 0
#6: LA 2000 666
#7: LA 2000 1
使用tidyverse
的选项为
library(tidyverse)
data %>%
group_by(city, year) %>%
mutate(target = replace(target, which(target != 0)[1], 666))
# A tibble: 7 x 3
# Groups: city, year [2]
# city year target
# <chr> <dbl> <dbl>
#1 NYC 2000 0
#2 NYC 2000 666
#3 NYC 2000 1
#4 LA 2000 0
#5 LA 2000 0
#6 LA 2000 666
#7 LA 2000 1
或与match
data %>%
group_by(city, year) %>%
mutate(target = replace(target, match(1, target), 666))
注意:即使特定组的“目标”中没有1,所有解决方案都可以工作
例如
data$target[6:7] <- 0
data %>%
group_by(city, year) %>%
mutate(target = replace(target, which(target != 0)[1], 666))
# A tibble: 7 x 3
# Groups: city, year [2]
# city year target
# <chr> <dbl> <dbl>
#1 NYC 2000 0
#2 NYC 2000 666
#3 NYC 2000 1
#4 LA 2000 0
#5 LA 2000 0
#6 LA 2000 0
#7 LA 2000 0
答案 1 :(得分:1)
使用dplyr
可以在组中使用which.max
,然后在666之前replace
来查找第一个非零元素的索引。
library(dplyr)
data %>%
group_by(city, year) %>%
mutate(target = replace(target, which.max(target != 0), 666))
# city year target
# <chr> <dbl> <dbl>
#1 NYC 2000 0
#2 NYC 2000 666
#3 NYC 2000 1
#4 LA 2000 0
#5 LA 2000 0
#6 LA 2000 666
#7 LA 2000 1
您还可以对ifelse
使用相同的东西
data %>%
group_by(city, year) %>%
mutate(target = ifelse(row_number() == which.max(target != 0), 666, target))
答案 2 :(得分:0)
对于data.table,请使用mult =参数进行连接,以仅编辑符合连接条件的第一行(如果有)
> data[.(unique(city), 1), on=.(city, target), mult="first", target := 999]
> data
city year target
1: NYC 2000 0
2: NYC 2000 999
3: NYC 2000 1
4: LA 2000 0
5: LA 2000 0
6: LA 2000 999
7: LA 2000 1