【问题标题】:Filter rows in dataframe by number of rows per level of a factor按因子的每个级别的行数过滤数据框中的行
【发布时间】:2013-01-21 13:30:46
【问题描述】:

我有一个数据框,其中一列作为具有多个级别的因子。我想提取该列没有唯一值的行(即该级别存在于多行中)。

所以对于一些简单的测试数据:

factor dat1 dat2 dat3
     a  1.0  1.0  1.0
     a  1.0  0.9  1.0
     b  0.9  0.8  0.6
     c  0.9  1.0  0.0

我只想保留前两行。做这个的最好方式是什么?最好我想进行更一般的查询,即提取至少 3 行、正好 2 行等中存在的因子级别的行。

【问题讨论】:

    标签: r filter dataframe


    【解决方案1】:

    这是table 的解决方案(假设数据框的名称是df):

    nRows <- 2 # minimum number of occurrences
    
    tab <- table(df$factor) # count
    
    df[df$factor %in% names(tab)[tab >= nRows], ] # extract rows
    

    如果您想改用精确标准,请将&gt;= 更改为==

    结果:

      factor dat1 dat2 dat3
    1      a    1  1.0    1
    2      a    1  0.9    1
    

    【讨论】:

    • 谢谢!我只知道table()
    【解决方案2】:

    对于这些类型的问题,我喜欢使用ave() 来生成一个长度与我的数据集中要匹配的行数相同的向量。我发现它比names() 更直接,因为table() 方法需要:

    ## Your data
    mydf <- read.table(header = TRUE, 
              stringsAsFactors = FALSE, 
              text = "factor dat1 dat2 dat3
                      a  1.0  1.0  1.0
                      a  1.0  0.9  1.0
                      b  0.9  0.8  0.6
                      c  0.9  1.0  0.0")
    
    ## Your vector to match against
    factorlengths <- ave(as.numeric(mydf$factor), 
                         mydf$factor, FUN = length)
    factorlengths
    # [1] 2 2 1 1
    
    ## The subsetting
    mydf[factorlengths > 1, ]
    #   factor dat1 dat2 dat3
    # 1      a    1  1.0    1
    # 2      a    1  0.9    1
    mydf[factorlengths == 1, ]
    #   factor dat1 dat2 dat3
    # 3      b  0.9  0.8  0.6
    # 4      c  0.9  1.0  0.0
    

    如果mydf$factor 的值实际上是因子,则必须改用ave(as.numeric(as.character(mydf$factor...

    【讨论】:

      【解决方案3】:

      这里有一个不同的方法供您考虑:

      mydf <- data.frame(fac = c("a", "a", "b", "c", "d", "d", "e"),
      dat1 = rnorm(7), dat2 = rnorm(7), dat3 = rnorm(7))
      
      library("plyr")
      
      cts <- count(mydf, vars = "fac")
      keep <- as.character(subset(cts, freq > 1)$fac)
      keep2 <- mydf$fac %in% keep
      mydf2 <- mydf[keep2,]
      

      转换:

        fac        dat1       dat2       dat3
      1   a  0.83565861  0.2293744 -1.2932864
      2   a -0.05509087  0.1995655 -1.7961443
      3   b -0.82794260  1.6314641 -0.3622872
      4   c  0.13907037 -0.4560306 -0.3751849
      5   d -0.30057042  0.8347340  0.4798789
      6   d -1.15576099 -0.5945094 -0.3124572
      7   e  1.17671034  0.1453544 -2.6906382
      

      到:

        fac        dat1       dat2       dat3
      1   a  0.83565861  0.2293744 -1.2932864
      2   a -0.05509087  0.1995655 -1.7961443
      5   d -0.30057042  0.8347340  0.4798789
      6   d -1.15576099 -0.5945094 -0.3124572
      

      我认为可能有一个使用 duplicated 的单行代码,但这并不能完全返回在这种情况下所需的内容。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-11-17
        • 2014-02-11
        • 2013-10-29
        • 2018-04-04
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多