按组将函数应用于整个数据表
Posted
技术标签:
【中文标题】按组将函数应用于整个数据表【英文标题】:Applying a function to the whole data table by groups 【发布时间】:2022-01-19 16:17:54 【问题描述】:假设如下数据表:
a = runif(40)
b = c(rep(NA,5), runif(5), rep(NA,3),runif(3),NA,runif(3), c(rep(NA,3), runif(7), rep(NA,4), runif(3), NA,NA, runif(1)))
c = rep(1:4,each=10)
DT = data.table(a,b,c)
我想为 c 中的每个唯一值消除 b 中具有第一个 NA 值的行(当 c==1 时为第一个 NA,当 c==2 时...),但不是带有 NA 的行之后。
我可以通过使用循环来做到这一点:
for(i in unique(DT$c))
first_NA = which(DT$c==i)[1]
last_NA = which(!is.na(DT[,b]) & DT$c==i)[1] - 1
DT = DT[-c(first_NA:last_NA)]
但我想知道是否有任何更简单的方法可以通过使用组(数据表中的 by 或 dplyr 中的 groupby)对整个数据表使用函数,而不仅仅是将其应用于列。
谢谢!
【问题讨论】:
【参考方案1】:您可以通过过滤掉b中的第一个NA值
DT[, .SD[cumsum( !is.na(b) ) != 0], by = .(c)]
【讨论】:
【参考方案2】:您必须标记这些行,然后保留未标记的行。
# mark values
DT <- DT[, by=c,
flag := is.na(b[1]) # first value of b is NA
& (seq_len(.N)==1) # only for first value
]
# discard marked
DT <- DT[(!flag)]
# remove flag
DT[, flag:=NULL]
或连续
DT[, by=c, flag:=is.na(b[1]) & (seq_len(.N)==1)][(!flag)][, flag:=NULL]
【讨论】:
这不会返回预期的输出。以上是关于按组将函数应用于整个数据表的主要内容,如果未能解决你的问题,请参考以下文章