我有一个很大的数据框架; 100,000个变量的100,000次观测。
在所有观察中,大多数变量实际上都是0,我想删除那些变量/列。
我尝试了以下内容,
data <- data[apply(data, 2, function(x){all(x == 0)})]
但申请需要花费大量时间来解决。
我尝试了while
,以防问题同时适用于所有data
。
i <- 1
while (i <= ncol(data)) {
if (all(data[i] == 0)) {
data[i] <- NULL
} else {
i <- i+1
}
}
但是我一直遇到同样的问题,花了很多时间。
所以,
,最重要的是
答案 0 :(得分:1)
你的问题令人困惑。我假设您要删除变量,即列。您可以使用any
自动强制值来键入logical。关于comparison of floating point numbers的常见警告适用。如果你想安全地玩它,你需要测试双精度是否小于某个精度值,这个速度会慢一些,但是正确地说它是正确的。
DF <- data.frame(x = 1:3, y = 1:3/10, z = 0)
DF[] <- lapply(DF, function(x) if (any(x)) x else NULL)
#Warning messages:
#1: In any(x) : coercing argument of type 'double' to logical
#2: In any(x) : coercing argument of type 'double' to logical
# x y
#1 1 0.1
#2 2 0.2
#3 3 0.3
set.seed(42)
DF2 <- as.data.frame(matrix(sample(0:1, 700*1e5, TRUE, prob = c(0.999999, 0.000001)), ncol = 700))
system.time(DF2[] <- lapply(DF2, function(x) if (any(x)) x else NULL))
#user system elapsed
#0.10 0.02 0.11
更安全的选项:
set.seed(42)
DF2 <- as.data.frame(matrix(sample(0:1, 700*1e5, TRUE, prob = c(0.999999, 0.000001)), ncol = 700))
system.time(DF2[] <- lapply(DF2, function(x) if (any(x > 1e-16)) x else NULL))
#user system elapsed
#0.34 0.11 0.45
答案 1 :(得分:1)
使用像colSums
这样的矢量化操作可加快我机器上的操作 -
> set.seed(123)
> df = data.frame(matrix(sample(0:1,100000*700,replace = T,prob = c(0.9999999,0.0000001)), ncol = 700))
> system.time(df1 <- df[apply(df, 2, function(x){all(x == 0)})])
user system elapsed
1.386 0.821 2.225
> system.time(df2 <- df[,which(colSums(df)==0)])
user system elapsed
0.243 0.082 0.326
> identical(df1, df2)
[1] TRUE