将 R 中的 data.table 中的所有 NA 替换为 0

Dan*_*nka 4 loops r data.table

我有一个data.table有很多列的。有 4 列我想NA用 0 替换。

我有一个可行的解决方案:

  claimsMonthly[is.na(claim9month),claim9month := 0
          ][is.na(claim10month),claim10month := 0
            ][is.na(claim11month),claim11month := 0
              ][is.na(claim12month),claim12month := 0]
Run Code Online (Sandbox Code Playgroud)

然而,这是相当重复的,我想通过使用循环来减少这种情况(但不确定这是否是最聪明的想法?):

  for (i in 9:12){
    claimsMonthly[is.na(paste0("claim", i, "month")), paste0("claim", i, "month") := 0]
  }
Run Code Online (Sandbox Code Playgroud)

当我运行这个循环时,什么也没有发生。我猜是因为约定的回报paste0()"claim12month"所以我得到了in.na("claim12month")。其结果是FALSE尽管我的数据中有这样的事实NA。我想这与引用有关?

这不是我第一次遇到使用paste0()或运行循环的问题data.table,所以我一定在这里遗漏了一些重要的东西。

任何想法如何解决这一问题?

akr*_*run 5

我们可以指定.SDcols与列的名称 ('nm1'),循环.SD(Data.table 的子集) 并将 NA 分配给 0 (replace_na来自tidyr)

library(data.table)
library(tidyr)
nm1 <- paste0("claim", 9:12, "month")
setDT(claimsMonthly)[, (nm1) := lapply(.SD, replace_na, 0), .SDcols = nm1]
Run Code Online (Sandbox Code Playgroud)

或者正如@jangorecki 在评论中提到的那样,nafill来自data.table会更好

setDT(claimsMonthly)[, (nm1) := lapply(.SD, nafill, fill = 0), .SDcols = nm1]
Run Code Online (Sandbox Code Playgroud)

或使用循环,通过指定(对于行索引)和对于列索引/名称,set根据每列中的 NA 值将感兴趣的列分配为 0ij

for(j in nm1){
    set(claimsMonthly, i = which(is.na(claimsMonthly[[j]])), j =j, value = 0)
 }
Run Code Online (Sandbox Code Playgroud)

或者与setnafill

setnafill(claimsMonthly, cols = nm1, fill = 0)
Run Code Online (Sandbox Code Playgroud)