我在for
循环和apply
函数之间遇到了巨大的时差。
我有一个数据帧(alldat),包含大约200k条记录和73列我想检查每列中NA的百分比,并将结果作为新DF返回给我进行检查。我用2种方法完成了它:
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秒
我做错了吗?知道造成这种时差的原因吗?
答案 0 :(得分:1)
日期框架在内部与列表非常相似,每列都是列表中的单独条目。您可以使用$
运算符查看此内容。这允许您指定列,类似于在列表中指定命名条目。
当您apply
时,正如Natrave Drova在评论中已经提到的那样,您隐式将您的entiry数据帧转换为矩阵。如果您的数据帧具有不同的数据类型,例如数字列和字符列,则它会将所有值强制转换为公共类型(通常是字符)。如果你的数据帧很大(并且200k * 73的值是强制的那么大),这可能是一个非常昂贵的操作。
因此,如果您想要正确地将*apply
函数与for循环进行比较,则应该使用lapply
进行尝试。