【问题标题】:How do you subset a data frame in R based on a minimum sample size如何根据最小样本量对 R 中的数据框进行子集化
【发布时间】:2013-08-16 01:47:37
【问题描述】:

假设您有一个包含两个级别因子的数据框,如下所示:

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

等等

我如何subset 这个数据框(“df”,如果你愿意的话)基于 Factor1 和 Factor2 的组合 (Fact1*Fact2) 有超过 2 个观察值的条件?您可以使用subset 中的length 参数来执行此操作吗?

【问题讨论】:

    标签: r subset


    【解决方案1】:
    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 ...)
    【解决方案2】:

    假设您的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))),]
    

    【讨论】:

      【解决方案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。这是您最后一步的更自动化方法:mydata[mydata$inter %in% names(which(table(mydata$inter) &gt; 2)), ]
      • 谢谢@Ananda!。我一直在尝试,但没有成功。
      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 2020-05-24
      • 1970-01-01
      • 1970-01-01
      • 2020-10-17
      • 2013-08-15
      • 1970-01-01
      • 2013-07-11
      相关资源
      最近更新 更多