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

3

我有一个关于R中自然语言处理的问题。我的数据非常大,因此我需要将我的数据缩减以进行进一步分析并应用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个零的组合? - Rui Barradas
5个回答

3
你也可以使用 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
使用colSums()函数:
df[, colSums(abs(df)) > 0]

即当且仅当绝对值之和为零时,列才全部为零。

如果一列只有零,那么为什么要取绝对值? - Rui Barradas
2
它可能有1,-1,那么总和仍将为零。 - VitaminB16

2
这是我会的做法:
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

1
另一个tidyverse的解决方案。使用selectwhere代替select_if。请保留HTML标签。
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)

0

这个问题是另一个SO问题的简化版。以下是受最佳答案启发的代码。

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 是的,在LHS中将NULL分配给列号。 - Rui Barradas
好的,我刚看到你修改了标签。 - Waldi
@Waldi,nlp和e1071标签与问题无关。它们可能与Op试图解决的问题的一部分有关,但对于这个问题并不需要它们。 - Rui Barradas
感谢您的澄清,我同意。我的意思是您添加了 data.table,这也可以。 - Waldi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接