使用 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
我有一个包含 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