在data.table lapply函数中应用Counter

时间:2017-03-06 03:57:14

标签: r data.table

我想跟踪lapply处理data.table中列的方式。我通常在读取大量文件时这样做,但我在想是否也可以为列操作执行此操作。具体来说,假设我想使用NA方法替换locf(),并希望在处理每个变量时查看状态。

我注意到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]

(我在create a dataframe with random numbers中从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"

然后它开始处理,这是违反直觉的。有没有办法在处理列时跟踪列?

1 个答案:

答案 0 :(得分:1)

我认为这个问题是由逐行分组引起的。

这对我有用:

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的版本在100 000行中占用0.44。这是加速大约600次。

顺便说一句:na.locf()在按行分组的情况下无法按预期工作。

为了确保在计算期间 打印,我在调用counter之前和之后打印了NA个元素的数量

在回复this comment by the OPmy reply后,我修改了第一个na.locf()语句以打印cat()的长度,以展示关键效果行分组x