【问题标题】:Remove rows from dataframe that contains only 0 or just a single 0从仅包含 0 或仅包含单个 0 的数据框中删除行
【发布时间】:2014-10-01 22:50:54
【问题描述】:

我正在尝试在 R 中创建一个函数,该函数将允许我根据行是否包含其中包含零的单个列来过滤我的数据集。此外,有时我只想删除所有列中为零的行。

还有,这就是有趣的地方;并非所有列都包含数字,列数可能会有所不同。

我已尝试将我的一些数据与我想要获得的结果粘贴到此处。

unfiltered:
    ID  GeneName    DU145small  DU145total  PC3small    PC3total
    1   MIR22HG     33221.5     1224.55     2156.43     573.315
    2   MIRLET7E    87566.1     7737.99     25039.3     16415.6
    3   MIR612      0           0           530.068     0
    4   MIR218-1    0           0           1166.88     701.253
    5   MIR181B2    70723.2     3958.01     6209.85     1399.34
    6   MIR218-2    0           0           0           0
    7   MIR10B      787.516     330.556     0           20336.4
    8   MIR3176     0           0           0           0

any rows with containing a zero removed:
    ID  GeneName    DU145small  DU145total  PC3small    PC3total
    1   MIR22HG     33221.5     1224.55     2156.43     573.315
    2   MIRLET7E    87566.1     7737.99     25039.3     16415.6
    5   MIR181B2    70723.2     3958.01     6209.85     1399.34

only rows that is all zero is filtered away:
    ID  GeneName    DU145small  DU145total  PC3small    PC3total
    1   MIR22HG     33221.5     1224.55     2156.43     573.315
    2   MIRLET7E    87566.1     7737.99     25039.3     16415.6
    3   MIR612      0           0           530.068     0
    4   MIR218-1    0           0           1166.88     701.253
    5   MIR181B2    70723.2     3958.01     6209.85     1399.34
    7   MIR10B      787.516     330.556     0           20336.4

我确实找到了一种方法来删除其中至少包含 1 个零的任何行,但它通过将所有零与 NA 交换然后使用 complete.cases 进行过滤来“作弊”。

此外,通过这样做,它会删除所有 GeneName 中包含零的行(对于 MIR10B)。

我可以通过使用 for 循环来解决它,但有人告诉我,R 中的循环非常无效,因此希望避免这种解决方案。

编辑:虽然 Xin Yin 的解决方案运行良好并将数据保存在数据框中,但 David Arenburg 的回答据说效率更高,应该使用。

【问题讨论】:

  • 如果df 是数据集。第一种情况是:df[!rowSums(!df[-(1:2)]),] 和第二种情况df[!rowSums(!df[-(1:2)])==4,]

标签: r filtering bioinformatics data-processing


【解决方案1】:

删除任何零的行:

df[!rowSums(df[-c(1:2)] == 0) >= 1,]

删除全为零的行:

df[!!rowSums(abs(df[-c(1:2)])),]

灵感来自this question

【讨论】:

    【解决方案2】:

    使用data.table(假设df 是您的数据集)

    library(data.table)
    setDT(df)[, .SD[!all(.SD[, -1, with = F] == 0)], by = GeneName]
    
    #    GeneName ID DU145small DU145total  PC3small  PC3total
    # 1:  MIR22HG  1  33221.500   1224.550  2156.430   573.315
    # 2: MIRLET7E  2  87566.100   7737.990 25039.300 16415.600
    # 3:   MIR612  3      0.000      0.000   530.068     0.000
    # 4: MIR218-1  4      0.000      0.000  1166.880   701.253
    # 5: MIR181B2  5  70723.200   3958.010  6209.850  1399.340
    # 6:   MIR10B  7    787.516    330.556     0.000 20336.400
    

    或者,如果您只想删除任何零的行

    setDT(df)[, .SD[!any(.SD[, -1, with = F] == 0)], by = GeneName]
    
    #    GeneName ID DU145small DU145total PC3small  PC3total
    # 1:  MIR22HG  1    33221.5    1224.55  2156.43   573.315
    # 2: MIRLET7E  2    87566.1    7737.99 25039.30 16415.600
    # 3: MIR181B2  5    70723.2    3958.01  6209.85  1399.340
    

    【讨论】:

    • 谢谢你的回答,它成功了。但是,我选择了另一个解决方案作为接受的答案,因为它将数据保存在 data.frame 中。
    • @KnightofniDK,您可以随时在对象上执行as.data.frame。使用apply 通常是最不推荐的方法,因为它非常非常慢,所以在这里的所有答案中,使用apply 的方法最差
    • 您确实有一个有效的观点。效率很重要,尤其是当数据集变得更大时。
    【解决方案3】:

    这样就可以了

    > (unfiltered <- read.table(text="
    +    ID  GeneName    DU145small  DU145total  PC3small    PC3total
    +     1   MIR22HG     33221.5     1224.55     2156.43     573.315
    +     2   MIRLET7E    87566.1     7737.99     25039.3     16415.6
    +     3   MIR612      0           0           530.068     0
    +     4   MIR218-1    0           0           1166.88     701.253
    +     5   MIR181B2    70723.2     3958.01     6209.85     1399.34
    +     6   MIR218-2    0           0           0           0
    +     7   MIR10B      787.516     330.556     0           20336.4
    +     8   MIR3176     0           0           0           0
    + ", header=T))
      ID GeneName DU145small DU145total  PC3small  PC3total
    1  1  MIR22HG  33221.500   1224.550  2156.430   573.315
    2  2 MIRLET7E  87566.100   7737.990 25039.300 16415.600
    3  3   MIR612      0.000      0.000   530.068     0.000
    4  4 MIR218-1      0.000      0.000  1166.880   701.253
    5  5 MIR181B2  70723.200   3958.010  6209.850  1399.340
    6  6 MIR218-2      0.000      0.000     0.000     0.000
    7  7   MIR10B    787.516    330.556     0.000 20336.400
    8  8  MIR3176      0.000      0.000     0.000     0.000
    > 
    > (any.zero <- unfiltered[!apply(unfiltered[, -c(1,2)], 1, function(row) any(row == 0)), ])
      ID GeneName DU145small DU145total PC3small  PC3total
    1  1  MIR22HG    33221.5    1224.55  2156.43   573.315
    2  2 MIRLET7E    87566.1    7737.99 25039.30 16415.600
    5  5 MIR181B2    70723.2    3958.01  6209.85  1399.340
    > (all.zero <- unfiltered[!apply(unfiltered[, -c(1,2)], 1, function(row) all(row == 0)), ])
      ID GeneName DU145small DU145total  PC3small  PC3total
    1  1  MIR22HG  33221.500   1224.550  2156.430   573.315
    2  2 MIRLET7E  87566.100   7737.990 25039.300 16415.600
    3  3   MIR612      0.000      0.000   530.068     0.000
    4  4 MIR218-1      0.000      0.000  1166.880   701.253
    5  5 MIR181B2  70723.200   3958.010  6209.850  1399.340
    7  7   MIR10B    787.516    330.556     0.000 20336.400
    

    【讨论】:

      【解决方案4】:

      在列子集上使用rowSums,试试这个:

      #dummy data
      df <- read.table(text="
      ID  GeneName    DU145small  DU145total  PC3small    PC3total
      1   MIR22HG     33221.5     1224.55     2156.43     573.315
      2   MIRLET7E    87566.1     7737.99     25039.3     16415.6
      3   MIR612      0           0           530.068     0
      4   MIR218-1    0           0           1166.88     701.253
      5   MIR181B2    70723.2     3958.01     6209.85     1399.34
      6   MIR218-2    0           0           0           0
      7   MIR10B      787.516     330.556     0           20336.4
      8   MIR3176     0           0           0           0",
                       header=TRUE)
      #remove any zero
      df[ !rowSums(df[,colnames(df)[(3:ncol(df))]]==0)>=1, ]
      
      #remove all zero
      df[ !rowSums(df[,colnames(df)[(3:ncol(df))]]==0)==ncol(df)-2, ]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多