R 分组方式,并在数据表中查找每组中第一个非零的索引
我在R中有一个数据表,看起来像:R 分组方式,并在数据表中查找每组中第一个非零的索引,r,group-by,dplyr,data.table,R,Group By,Dplyr,Data.table,我在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", "
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
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)
)
cutoff\u thresh cutoff}
助手%
组别(城市,年份)%>%
突变(阈值=检测指数(.x=目标,
.f=截止值\阈值,
截止值=0)
)
它产生给定年份中第一个非零元素出现的确切日期,
它从每年的第一天开始计算。因此,如果2000年有365天,而2001年的第2天我们是非零的,它返回
的2
(纽约,2001)
,而不是365+2
。毫不奇怪 由于数据集已经是一个数据表
,因此使用数据表
方法可能更有效。按“城市”、“年份”分组,获取第一个非零元素(“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
或与匹配
data %>%
group_by(city, year) %>%
mutate(target = replace(target, match(1, target), 666))
注意:即使特定组的“目标”中没有1,所有解决方案都有效
e、 g
data$target[6:7]%
组别(城市,年份)%>%
突变(target=replace(target,其中(target!=0)[1],666))
#一个tibble:7x3
#组别:城市,年份[2]
#城市年目标
#
#1纽约市2000 0
#2纽约市2000 666
#3纽约市2000 1
#4洛杉矶2000 0
#5洛杉矶2000 0
#6洛杉矶2000 0
#7洛杉矶2000 0
使用dplyr
您可以使用组中的which.max
找到第一个非零元素的索引,并将其替换为666
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
使用data.table,使用mult=参数连接,仅编辑符合连接条件的第一行(如果有)
很好的技巧,使用
which.max
查找第一个非零元素。另一种data.table
方法使用replace
类似于您的第一种方法:data[,target:=replace(target,cumsum(target!=0)=1L,666L),by=(city,year)]
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
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
data %>%
group_by(city, year) %>%
mutate(target = ifelse(row_number() == which.max(target != 0), 666, target))
> 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