我有这样的数据表.
> dt
ID value
1 a v1
2 a v2
3 a v3
4 a v4
5 a v5
6 b v6
7 b v7
8 b v8
Run Code Online (Sandbox Code Playgroud)
我想为每个ID只选择一个值.它可以是第一个值或最后一个值.我就是这样做的.
unique_id_value_mapping <- dt[, list(new_value=head(.SD[,value],1)), by="ID"]
Run Code Online (Sandbox Code Playgroud)
但对于大型数据表(约10万行),需要花费大量时间.谁知道更快的方法呢?
更新
建议上述问题的答案很好.但是,如果我需要根据某些条件选择值,该怎么办?考虑一个数据表
> dt
ID value days
1 a v1 2
2 a v2 4
3 a v3 7 *
4 a v4 7
5 a v5 1
6 b v6 5 *
7 b v7 4
8 b v8 2
Run Code Online (Sandbox Code Playgroud)
并且我想为每个ID选择一个值,只要该ID的最大天数.我就是这样做的.
unique_id_value_mapping <- dt[, list(new_value=head(.SD[days==max(days),value])), by="ID"]
Run Code Online (Sandbox Code Playgroud)
怎么做得更快?
尝试
dt[, list(new_value=value[1L]), ID]
dt[, list(new_value= value[.N]), ID]
Run Code Online (Sandbox Code Playgroud)
使用更大的数据集
set.seed(24)
df1 <- data.frame(ID= sample(1:100, 1e6, replace=TRUE),
value=rnorm(1e6))
dt1 <- as.data.table(df1)
system.time(dt1[, list(new_value=value[1L]), ID])
# user system elapsed
# 0.012 0.000 0.013
system.time(dt1[, list(new_value=value[.N]), ID])
# user system elapsed
# 0.011 0.000 0.012
Run Code Online (Sandbox Code Playgroud)
根据新的更新,正如@David Arenburg所建议的那样
dt[, list(new_value = value[which.max(days)]), by = ID]
# ID new_value
#1: a v3
#2: b v6
Run Code Online (Sandbox Code Playgroud)
假设您需要符合条件的行
dt[dt[, .I[which.max(days)], by = ID]$V1]
# ID value days
#1: a v3 7
#2: b v6 5
Run Code Online (Sandbox Code Playgroud)
要么
dt[, .SD[which.max(days)], by = ID]
Run Code Online (Sandbox Code Playgroud)