R:更有效地对数据进行子集化

R: Subsetting data more efficiently

我有一个数据集 df:

df=data.frame(rbind(c("A",1,1,"abc"),
                    c("B",0,0,"def"),
                    c("C",0,1,"hep"),
                    c("A",1,1,"hit"),
                    c("B",0,1,"occ"),
                    c("C",1,1,"tem"),
                    c("A",1,1,"twi"),
                    c("B",1,1,"twa"),
                    c("C",1,1,"mit"),
                    c("A",1,1,"mot"),
                    c("C",1,1,"mot"),
                    c("B",1,1,"mjak")))
names(df)=c("id","v1","v2","check")

我想在 DF 中创建一个 ID 子集,其中包含 "check" 列中 "ch.vars" 向量中包含的值。

ch.vars=c("abc","hit","mot","twi","mjak")

如果 id 包含 "ch.vars" 中给出的值以外的任何值,则它们将被排除在 dataset.For 示例中,id B 和 C 在检查列中包含其他值,因此它们将被排除在子集中。

这是我目前尝试过的方法:

df$check.var=ifelse(df$check %in% ch.vars,1,0)
df=arrange(df,id)

st1=filter(df,check.var==0)
st1=as.character(unique(st1$id))

df2=df[!df$id %in% st1,]

> df2
  id v1 v2 check check.var
1  A  1  1   abc         1
2  A  1  1   hit         1
3  A  1  1   twi         1
4  A  1  1   mot         1

这行得通,但我想知道是否有更有效的方法来做到这一点,即以更少的步骤实现结果。谢谢!

您可以使用 dplyr 包中的 group_byfilter 执行此操作:

library(dplyr)
df2 = df %>%
  group_by(id) %>%
  filter(all(check %in% ch.vars))

还有一个data.table解决方案:

library(data.table)
data.table(df)[,.SD[all(check%in%ch.vars)],by="id"]
#   id v1 v2 check
#1:  A  1  1   abc
#2:  A  1  1   hit
#3:  A  1  1   twi
#4:  A  1  1   mot

您也可以将 setkey 用于 id 以使其更快。