【问题标题】:Remove all columns or rows with only zeros out of a data frame从数据框中删除所有只有零的列或行
【发布时间】:2021-08-23 22:59:43
【问题描述】:

我对 R 中的 NLP 有一个问题。我的数据非常大,因此我需要减少数据以进行进一步分析,以便在其上应用 SVM。

我有一个像这样的文档术语矩阵:

Document WordY WordZ WordV WordU WordZZ
1        0     0     0     1     0
2        0     2     1     2     0
3        0     0     1     1     0

所以在这个例子中,我想按列 WordY 和 WordZZ 减少数据帧,因为这些列对于这个数据帧没有特定的含义。这是否可以使用一个特定的顺序删除所有只有零值的列?我的问题是我的数据框太大,无法用一个订单删除每个特定列。它在数据框中大约有 4.0000.0000 列。

提前谢谢你们。 干杯, 汤姆

【问题讨论】:

  • 为什么4.0000.0000中的4个零组?

标签: r dataframe data.table tidyverse


【解决方案1】:

我会这样做:

dplyr::select_if(YOUR_DATA, ~ any(. != 0))

返回:

  Document WordZ WordV WordU
1        1     0     0     1
2        2     2     1     2
3        3     0     1     1

【讨论】:

    【解决方案2】:

    你也可以使用sapply:

    df <- read.table(text=
    "Document WordY WordZ WordV WordU WordZZ
    1        0     0     0     1     0
    2        0     2     1     2     0
    3        0     0     1     1     0",header=T)
    
    
    df[,sapply(df,function(x) any(x!=0))]
    
      Document WordZ WordV WordU
    1        1     0     0     1
    2        2     2     1     2
    3        3     0     1     1
    

    性能对比:

    Unit: microseconds
                                          expr      min        lq      mean    median        uq      max neval
     df[, sapply(df, function(x) any(x != 0))]  156.401  190.9515  236.3650  225.5510  271.0005  371.201   100
                    df[, colSums(abs(df)) > 0]  345.601  398.6005  555.2809  451.8010  506.8005 6005.601   100
            dplyr::select_if(df, ~any(. != 0)) 2282.301 2620.9015 2939.9239 2773.1510 3019.9005 6588.402   100
     df[, `:=`(which(colSums(df) == 0), NULL)]  223.201  262.4015  337.5781  297.9015  352.2020 2528.900   100
    

    【讨论】:

      【解决方案3】:

      这个问题是this other SO question 的简单版本。这是在接受的答案中启发的代码。

      df1[, which(colSums(df1) == 0) := NULL]
      

      数据创建代码

      set.seed(2021)
      df1 <- replicate(5, rbinom(10, 1, 0.5))
      df1 <- as.data.table(df1)
      df1[, 3] <- 0
      

      【讨论】:

      • @Waldi 是的,将 NULL 分配给 LHS 中的列号。
      • 好的,刚刚看到你修改了标签
      • @Waldi 标签 nlp 和 e1071 与 question 无关。它们可能与 Op 试图解决的 部分问题有关,但这个问题不需要它们。
      • 感谢您的澄清,我同意。我的意思是您添加了data.table,这也可以。
      【解决方案4】:

      使用colSums()

      df[, colSums(abs(df)) > 0]
      

      即当且仅当绝对值之和为零时,一列只有零。

      【讨论】:

      • 如果一列只有零,那为什么是绝对值?
      • 它可能有1, -1,那么总和仍然为零
      【解决方案5】:

      另一个tidyverse 解决方案。 select_ifselectwhere 的以下用法所取代。

      library(tidyverse)
      
      dat2 <- dat %>%
        select(where(~any(. != 0)))
      dat2
      #   Document WordZ WordV WordU
      # 1        1     0     0     1
      # 2        2     2     1     2
      # 3        3     0     1     1
      

      数据

      dat <- read.table(text = "Document WordY WordZ WordV WordU WordZZ
      1        0     0     0     1     0
      2        0     2     1     2     0
      3        0     0     1     1     0",
                        header = TRUE)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-22
        • 2021-06-18
        • 2014-02-27
        • 2014-04-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-05
        • 2019-02-14
        相关资源
        最近更新 更多