如何在R中根据最小样本量对数据框进行子集筛选

3
假设您有一个包含两个级别因子的数据框,看起来像这样:
Factor1    Factor2    Value
A          1          0.75
A          1          0.34
A          2          1.21   
A          2          0.75 
A          2          0.53
B          1          0.42
B          2          0.21  
B          2          0.18
B          2          1.42

如何根据Factor1和Factor2(Fact1*Fact2)的组合具有超过2个观测值的条件来对此数据框(如果您愿意,可以称其为“df”)进行子集操作?您可以使用subset中的length参数来实现吗?

3个回答

4
library(data.table)

dt = data.table(your_df)

dt[, if(.N > 2) .SD, list(Factor1, Factor2)]
#   Factor1 Factor2 Value
#1:       A       2  1.21
#2:       A       2  0.75
#3:       A       2  0.53
#4:       B       2  0.21
#5:       B       2  0.18
#6:       B       2  1.42

+1. 我认为很难超越那种语法。以前从未见过 if(.N ...) - A5C1D2H2I1M1N2O1R2T1

3
你可以使用interactiontable来查看每个交互作用的观察次数(mydata是你的数据),然后使用%in%来对数据进行子集筛选。
 mydata$inter<-with(mydata,interaction(Factor1,Factor2))
 table(mydata$inter)
A.1 B.1 A.2 B.2 
  2   1   3   3 

mydata[!mydata$inter %in% c("A.1","B.1"), ]
  Factor1 Factor2 Value inter
3       A       2  1.21   A.2
4       A       2  0.75   A.2
5       A       2  0.53   A.2
7       B       2  0.21   B.2
8       B       2  0.18   B.2
9       B       2  1.42   B.2

根据@Ananda的评论更新:在创建交互变量后,您可以使用以下一行代码。
mydata[mydata$inter %in% names(which(table(mydata$inter) > 2)), ]

1
+1. 这里有一个更自动化的方法来完成你最后一步:mydata[mydata$inter %in% names(which(table(mydata$inter) > 2)), ] - A5C1D2H2I1M1N2O1R2T1
谢谢@Ananda!我一直在尝试,但没有成功。 - Metrics

3

假设你的data.frame叫做mydf,你可以使用ave来创建一个逻辑向量来帮助进行子集筛选:

mydf[with(mydf, as.logical(ave(Factor1, Factor1, Factor2, 
                           FUN = function(x) length(x) > 2))), ]
#   Factor1 Factor2 Value
# 3       A       2  1.21
# 4       A       2  0.75
# 5       A       2  0.53
# 7       B       2  0.21
# 8       B       2  0.18
# 9       B       2  1.42

这里是 ave 对你的组合进行计数。注意,ave 返回一个与你的 data.frame 行数相同长度的对象(这使得子集更加方便)。

> with(mydf, ave(Factor1, Factor1, Factor2, FUN = length))
[1] "2" "2" "3" "3" "3" "1" "3" "3" "3"

下一步是将该长度与您的阈值进行比较。为此,我们需要一个匿名函数作为我们的 FUN 参数。
> with(mydf, ave(Factor1, Factor1, Factor2, FUN = function(x) length(x) > 2))
[1] "FALSE" "FALSE" "TRUE"  "TRUE"  "TRUE"  "FALSE" "TRUE"  "TRUE"  "TRUE" 

快要完成了...但由于第一个项目是字符向量,因此我们的输出也是字符向量。 我们希望它是as.logical,这样我们就可以直接用它来子集化。


ave不能用于factor类的对象上,这种情况下你需要做一些类似以下的操作:

mydf[with(mydf, as.logical(ave(as.character(Factor1), Factor1, Factor2, 
                               FUN = function(x) length(x) > 2))),]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接