r语言 - 在数据帧中的几行上提取具有匹配模式的 id



这是我正在处理的数据帧的示例:

id  string
1    no
1    yes
1    yes
2    no
2    yes
3    yes
3    yes
3    no

我想提取最后两行包含字符串"yes"stringid

所以结果将是:

id   string
 1    yes
 1    yes

而且我只有一个id 1.

我尝试使用 for 循环执行此操作,但由于我有超过 200 000 行,循环花费了太多时间:超过 5 分钟

我试过这个:

vec_id <- unique(df$id)
for(id in vec_id){
   if( tail(df[which(df$id == id),"string"])[1] & tail(df[which(df$id == id),"string"])[2] ){
      vec_id <- append(vec_id, id) 
     }

有什么功能或方法可以更快地完成此任务吗?

我们可以使用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[i, j, by]

一个基本的 R 替代方案是使用 splitlapply(带 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$iddf$string拆分为一个列表,该列表由 lapply 馈送到匿名函数。该函数为前 n-2 个元素返回 FALSE,然后为最后两个元素返回 TRUE TRUE 或 FALSE FALSE,具体取决于它们是否都是"是"。

然后使用向量删除不需要的观测值。

 df[dropper,]
  id string
2  1    yes
3  1    yes

最新更新