使用 ifelse( ) 将变量分配给 R 中的 tbl_df/data.frame 对象会导致 R 运行 内存不足

Using ifelse( ) to assign a variable to a tbl_df/data.frame object in R causes R to run short of memory

我有一个包含 4811616 行的数据集,由变量 A、B 和 C 组成。变量 C 有 NA,我想为 NA 的情况分配零。我进行如下操作:

df$A <- ifelse(is.na(df$A), 0, df$A) 

我收到一条错误消息说 R 运行 内存不足。这是不可能的,因为我在 Windows 7 上 运行 使用 36Gb 内存 运行 设置 R 的 64 位版本,使用 memory.limit(size=34000) 将内存分配给 R,并且是环境中唯一的对象是我的 128.5 Mb 数据框。此外,print(object.size(ifelse(is.na(df$A), 0, df$A)),units="MB) returns 36.7 Mb,所以不可能是 ifelse 语句产生的向量太大。

事实上,将向量分配给变量 x 不会导致 R 运行 内存不足。当我尝试将它分配给我的 tbl_df 时,问题就发生了。如果我将它分配给 data.frame(tbl_df),也会发生这种情况。

任何人都可以帮助我发现正在发生的事情并找到解决方法吗?

你可以试试data.table

library(data.table)
setDT(df)[is.na(A), A:=0][]

如果你需要替换所有列中的"NAs",你可以使用set,这样会非常有效。

for(j in seq_len(ncol(df))){
 set(df, i=which(is.na(df[[j]])), j=j, value=0)
}

使用更大的数据集

set.seed(495)
df1 <- as.data.frame(matrix(sample(c(NA,1:5),3*4811616,
  replace=TRUE), ncol=3, dimnames=list(NULL, LETTERS[1:3])))
system.time(setDT(df1)[is.na(A), A:=0])
#   user  system elapsed 
# 0.026   0.002   0.027 

只是为了与@lukeA的方法进行比较

system.time(df1$A[is.na(df1$A)] <- 0)
#  user  system elapsed 
# 0.140   0.004   0.144 

数据

set.seed(25)
df <- as.data.frame(matrix(sample(c(NA,1:5), 3*20,
   replace=TRUE), ncol=3, dimnames=list(NULL, LETTERS[1:3])))

你可以使用

df$A[is.na(df$A)] <- 0