在大型 ffdfs 上使用 apply
Using apply on large ffdfs
基本思路是这样的:我有一个很大的 ffdf
(大约 550 万 x 136 个字段)。我知道一个事实,即此数据框中的某些列的列都是 NA
。我如何找出哪些并适当地删除它们?
我的直觉是做类似的事情(假设 df
是 ffdf
):
apply(X=is.na(df[,1:136]), MARGIN = 2, FUN = sum)
这应该给我每个列的 NA
计数的向量,然后我可以找到哪些具有约 550 万 NA
值,使用 df <- df[,-c(vector of columns)]
删除它们,等。非常简单。
但是,apply
给我一个错误。
Error: cannot allocate vector of size 21.6 Mb
In addition: Warning messages:
1: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
2: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
3: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
4: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
这告诉我 apply
无法处理这种大小的数据帧。我可以使用其他替代方法吗?
使用起来更容易all(is.na(column))
。 sapply
/lapply
不起作用,因为 ffdf
对象不是列表。
您在代码中使用了 df[, 1:136]
。这将导致 ff
尝试将所有 136 列加载到内存中。这就是导致内存问题的原因。当您执行 df[1:136]
时不会发生这种情况。为最终结果建立索引时也会发生同样的情况:df <- df[,-c(vector of columns)]
将所有选定的列读入内存。
na_cols <- logical(136)
for (i in seq_len(136)) {
na_cols[i] <- all(is.na(df[[i]]))
}
res <- df[!na_cols]
试试这个例子:
#dummy data
df <- sample(1000000*5)
df <- data.frame( matrix(df,nrow = 1000000))
df$X3 <- NA
df$X6 <- NA
#list of col to remove or keep
colToRemove <- colnames(df)[ colSums(is.na(df[ ,1:6])) == nrow(df) ]
colToKeep <- setdiff(colnames(df), colToRemove)
#subset
res <- df[, colToKeep]
colnames(df)
#[1] "X1" "X2" "X3" "X4" "X5" "X6"
colnames(res)
#[1] "X1" "X2" "X4" "X5"
基本思路是这样的:我有一个很大的 ffdf
(大约 550 万 x 136 个字段)。我知道一个事实,即此数据框中的某些列的列都是 NA
。我如何找出哪些并适当地删除它们?
我的直觉是做类似的事情(假设 df
是 ffdf
):
apply(X=is.na(df[,1:136]), MARGIN = 2, FUN = sum)
这应该给我每个列的 NA
计数的向量,然后我可以找到哪些具有约 550 万 NA
值,使用 df <- df[,-c(vector of columns)]
删除它们,等。非常简单。
但是,apply
给我一个错误。
Error: cannot allocate vector of size 21.6 Mb
In addition: Warning messages:
1: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
2: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
3: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
4: In `[.ff`(p, i2) :
Reached total allocation of 3889Mb: see help(memory.size)
这告诉我 apply
无法处理这种大小的数据帧。我可以使用其他替代方法吗?
使用起来更容易all(is.na(column))
。 sapply
/lapply
不起作用,因为 ffdf
对象不是列表。
您在代码中使用了 df[, 1:136]
。这将导致 ff
尝试将所有 136 列加载到内存中。这就是导致内存问题的原因。当您执行 df[1:136]
时不会发生这种情况。为最终结果建立索引时也会发生同样的情况:df <- df[,-c(vector of columns)]
将所有选定的列读入内存。
na_cols <- logical(136)
for (i in seq_len(136)) {
na_cols[i] <- all(is.na(df[[i]]))
}
res <- df[!na_cols]
试试这个例子:
#dummy data
df <- sample(1000000*5)
df <- data.frame( matrix(df,nrow = 1000000))
df$X3 <- NA
df$X6 <- NA
#list of col to remove or keep
colToRemove <- colnames(df)[ colSums(is.na(df[ ,1:6])) == nrow(df) ]
colToKeep <- setdiff(colnames(df), colToRemove)
#subset
res <- df[, colToKeep]
colnames(df)
#[1] "X1" "X2" "X3" "X4" "X5" "X6"
colnames(res)
#[1] "X1" "X2" "X4" "X5"