【发布时间】:2017-07-05 06:37:45
【问题描述】:
我在for 循环和apply 函数之间遇到了巨大的时间差。
我有一个数据框 (alldat),其中包含大约 200k 条记录和 73 列我想检查每列中 NA 的百分比是多少,并将结果作为新的 DF 返回以供我检查。我已经通过两种方法完成了:
1) 带有for 循环的函数:
Nacheck = function(a){
a <- as.data.frame(a)
vecNA <- rep(NA, dim(a)[2])
for (i in 1:dim(a)[2]){
vecNA[i] <- sum(is.na(a[, i]))
}
rowss <- rep(nrow(a), length(vecNA))
NA_PCT <- vecNA/rowss
colna <- colnames(a)
datacheck <- as.data.frame(t(rbind(colna, NA_PCT)))
return(datacheck)
}
datacheck1 = Nacheck(alldat)
2)apply按列函数:
datacheck <- as.data.frame(apply(alldat,2,function (x) round(sum(is.na(x))/dim(alldat)[1], digits = 2)))
apply 函数耗时 4 秒,for 循环函数耗时不到 0.023 秒
start.time <- Sys.time()
datacheck <- as.data.frame(apply(alldat,2,function (x) round(sum(is.na(x))/dim(alldat)[1], digits = 2)))
end.time <- Sys.time()
time.takenapply <- end.time - start.time
time.takenapply
4.304 秒的时差
for 循环时间:
start.time <- Sys.time()
datacheck = Nacheck(alldat)
end.time <- Sys.time()
time.taken <- end.time - start.time
time.taken
0.02399993秒的时间差
我做错了吗?知道是什么导致了这个时差吗?
【问题讨论】:
-
apply函数将矩阵作为参数。输入数据到矩阵的内部转换可能会导致此时间差。另外我会改用lapply,因为您对列执行计算。 -
或
apply(df,2,function(x) sum(is.na(x))) -
不是这个原因,但为什么不使用
nrow(a),ncol(a)而不是dim(a)[1],dim(a)[2]? -
请提供一个可重现的例子
-
或许可以试试
colMeans(is.na(alldat))