data.table到位替换不起作用

时间:2018-05-09 15:07:04

标签: r data.table

我正在尝试使用以下代码替换非数字和逻辑列中的NA:

test_dt <- data.table(a = c("foo", "bar", "foo_bar"),
                      b = c(1.243, NA, 78454),
                      c = c(NA, NA, NA),
                      d = c(1.242345235, 2.3453255635, 475.253552352),
                      e = as.POSIXlt(c(NA, rep(Sys.time(), 2)), origin = as.POSIXlt(Sys.time(), "GMT"), tz = "GMT"),
                      f = c(T, F, NA),
                      g = as.Date(c(Sys.Date(), Sys.Date() - 5, NA)))

replaceNABlank <- function(DT, cols) {
  for (j in cols)
    set(DT,which(is.na(DT[[j]])) ,j, '')
  print(DT)
}

to_quote <- names(test_dt)[!(sapply(test_dt, class) %in% c('logical', 'numeric', 'integer'))]
options(useFancyQuotes = FALSE)

test_dt <- test_dt[, (to_quote) := lapply(.SD, as.character), .SDcols = to_quote]
test_dt1 <- replaceNABlank(test_dt, to_quote)

示例数据以代码形式提供。

输出print(DT)正确打印但test_dt1NULL。在我的案例中,我试图采用Fastest way to replace NAs in a large data.table的解决方案,但它似乎没有起作用。任何解释?

1 个答案:

答案 0 :(得分:2)

我认为这个问题与您的函数返回值有关。您使用print(DT),但如果要分配实际结果,则应返回DT。因此,一种方法是将函数更改为:

replaceNABlank <- function(DT, cols) {
  for (j in cols)
    set(DT,which(is.na(DT[[j]])) ,j, '')
  DT
}

但是,由于data.table::set通过引用更新列,您可能还会考虑执行以下操作:

test_dt[, (to_quote) := lapply(.SD, as.character), .SDcols = to_quote]
replaceNABlank(test_dt, to_quote)

test_dt
#         a         b  c          d                   e     f          g
#1:     foo     1.243 NA   1.242345                      TRUE 2018-05-09
#2:     bar        NA NA   2.345326 2066-09-15 06:43:38 FALSE 2018-05-04
#3: foo_bar 78454.000 NA 475.253552 2066-09-15 06:43:38    NA