以下是我正在处理的数据框示例:
id string
1 no
1 yes
1 yes
2 no
2 yes
3 yes
3 yes
3 no
我想提取最后两行包含id
列的字符串"yes"
的{{1}}。
结果将是:
string
我只有一个id string
1 yes
1 yes
,id
。
我尝试使用for循环执行此操作,但由于我有超过200 000行,因此循环花费了太多时间:超过5分钟。
我试过了:
1
是否有任何功能或方法可以更快地完成此任务?
答案 0 :(得分:4)
我们可以使用data.table
。转换' data.frame'到' data.table' (setDT(df1)
),按' id',if
all
分组'字符串'从最后两个观察结果是“是”'然后得到最后两个'字符串' (使用tail
)。
library(data.table)
setDT(df1)[, if(all(tail(string,2)=="yes")) .(string = tail(string,2)) , id]
# id string
#1: 1 yes
#2: 1 yes
注意:data.table语法通常为data.table[i, j, by]
。
答案 1 :(得分:2)
基本R替代方法是使用split
和lapply
(使用unlist
)来构造可用于执行行子集化的逻辑向量:
dropper <- unlist(lapply(split(df$string, df$id),
FUN=function(i) c(rep(FALSE, length(i) - 2),
rep(all(tail(i, 2) =="yes"), 2))),
use.names=FALSE)
dropper
FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE
此处,split
将df$string
拆分为df$id
的列表,该列表由lapply
提供给匿名函数。该函数对于前n-2个元素返回FALSE,然后对最后两个元素返回TRUE TRUE或FALSE FALSE,具体取决于它们是否为&#34;是。&#34;
然后使用向量来删除不需要的观察结果。
df[dropper,]
id string
2 1 yes
3 1 yes