从数据框中删除所有只有零的列或行
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_if
被 select
和 where
的以下用法所取代。
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)
我对 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_if
被 select
和 where
的以下用法所取代。
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)