2017-07-05 25 views
1

我在for循環和apply函數之間遇到了巨大的時間差。應用函數花費的時間比R中的For循環長100倍

我有一個數據幀(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秒,且對於循環功能需要小於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

'apply'函數將矩陣作爲參數。將輸入數據內部轉換爲矩陣可能會導致此時差。此外,我會使用'lapply'來代替,因爲您對列執行了計算。 –

+0

或'apply(df,2,function(x)sum(is.na(x))' – amonk

+0

不是原因,但爲什麼不使用'nrow(a)','ncol(a)'而不是dim(a)[1]',dim(a)[2]'? – digEmAll

回答

1

數據庫在內部非常類似於列表,每列都是列表中的單獨條目。您可以使用$運算符來查看。這允許您指定一個列,類似於在列表中指定一個命名條目。

當你做apply,正如Natrave Drova在評論中已經提到的那樣,你隱式地將你的entiry數據框轉換爲矩陣。如果您的數據框具有不同的數據類型,如數字列和字符列,它會將所有值強制轉換爲通用類型(通常是字符)。如果你的數據幀很大(200k * 73的值被視爲大),這可能是一個非常昂貴的操作。

所以,如果你想正確比較*apply函數和for-loops,你應該用lapply來代替它。

相關問題