从数据框中删除所有只有零的列或行

Remove all columns or rows with only zeros out of a data frame

我对 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 列。

提前谢谢大家。 干杯, 汤姆

我会这样做:

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

Returns:

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

您也可以使用 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

这个问题是 的简单版本。这是受已接受答案启发的代码。

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

使用colSums():

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

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

另一个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)