[英]Applying Counter in data.table lapply function
我想跟蹤有lapply
在處理列data.table
。 在讀取大量文件時,通常會執行此操作,但是我在考慮是否也可以對列操作執行此操作。 具體來說,假設我想使用locf()
方法替換NA
,並希望在處理每個變量時看到其狀態。
我注意到的是, data.table
首先打印計數器的輸出,然后開始處理。
這是測試代碼:
n <- 100000
reps <- 20
n1 <- 20
df <- data.table::as.data.table(as.data.frame(cbind(matrix(seq_len(n*n1), ncol=n1),
matrix(sample(0:1, n*reps, replace=TRUE), ncol=reps))))
#Randomly insert NAs
df <- data.table::as.data.table(lapply(df, function(cc)
cc[sample(c(TRUE, NA), prob = c(0.85, 0.15), size = length(cc), replace = TRUE) ]))
df$V1 <- c(1:n)
data.table::setDT(df)
counter <- 0
cols <- colnames(df)
df[, (cols):=lapply(.SD, function(x) {
counter <<- counter + 1
y <- na.locf(x, fromLast = TRUE, na.rm=FALSE)
if(counter %in% round(seq(from = 0, to = length(cols), length.out=35))) {
print(paste(round(counter/length(cols)*100,digits = 2),
"% has been processed;", counter, "columns"))
}
y
}), by = V1, .SDcols = cols]
(我從akrun的響應中竊取了隨機數據幀生成,以創建具有隨機數的數據幀 。)
執行代碼后會發生以下情況:
R首張照片:
[1] "2.5 % has been processed; 1 columns"
[1] "5 % has been processed; 2 columns"
[1] "10 % has been processed; 4 columns"
[1] "12.5 % has been processed; 5 columns"
[1] "15 % has been processed; 6 columns"
...
[1] "97.5 % has been processed; 39 columns"
[1] "100 % has been processed; 40 columns"
然后開始處理,這是違反直覺的。 在處理列時,我有什么方法可以跟蹤它們?
我相信問題是由按行分組引起的。
這對我有用:
library(data.table)
counter <- 0
df[, (cols) := lapply(.SD, function(x) {
counter <<- counter + 1
cat(counter, " ", length(x), " ")
cat(sum(is.na(x)), " ")
y <- zoo::na.locf(x, fromLast = TRUE, na.rm = FALSE)
cat(sum(is.na(y)), "\n")
return(y)
}), .SDcols = cols]
#1 14967 1
#2 14911 0
#3 14740 0
#...
#38 14928 0
#39 15090 1
#40 14811 0
請注意,我刪除了by = V1
因為逐行處理非常慢。 您使用by = V1
版本僅花了1000秒(!)就花了2.41秒,而沒有逐行使用by
的版本就花了10萬行花了0.44秒。 那是大約600倍的加速。
順便說一句: na.locf()
無法按行分組正常工作。
為了確保在計算期間打印counter
,我在調用na.locf()
之前和之后都打印了NA
元素的數量。
為了響應OP的評論和我的回復 ,我修改了第一條cat()
語句以也打印x
的長度,以演示by = V1
進行逐行分組的關鍵作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.