我是R的新手,我在google上搜索了以下问题的解决方案。
我有
DT = data.table(y=c("a",NA,NA), y_1=c(NA,3,6), y_2=c(1,NA,3), y_3=c(1,1,1)).
我想创建一个传递数据表的函数和需要更改的列。
fun <- function(dt, var)
{
dt[,(var) := ifelse(!(is.na(get(var))), get(paste0(var,"1")),
ifelse(!(is.na(get(paste0(var,"1")), get(paste0(var,"2")...))]
return(dt)
}
我想将y
变量NA
中的值替换为y_1
中的值,如果它们不是NULL
,或者替换为{{1} }} 等等。像这样我想创建一个可以接受不同变量但具有相同结尾的函数。
更新:Uwe,感谢您指出上一个问题。我发现它很有用。但是,我的要求略有不同。我需要对其他变量进行相同的更新,其中值为NA。例如,我需要为(x,x_1,x_2,x_3 ...),(z,z_1,z_2,z_3 ..)以及除y之外的一些其他变量执行此操作。有没有办法使用lapply或函数来做到这一点。
提前致谢。
答案 0 :(得分:1)
OP正在寻找locf
方法的变体(最后一次观察结果),例如实现为zoo::na.locf()
。虽然na.locf()
通常应用于data.frame的向量或列,但OP正在查找应用于data.table
的每一行但仅限于列的特定子集的变体。因此,该函数被命名为na.locl()
(最后一次观察 left )。
此外,data.table
将在适当的位置更新,例如,无需复制。列以特定方式命名,例如x
,x_1
,x_2
,x_3
等。因此,x
是一种列的子名称>基本名称。
下面的函数将查看给定data.table
列的特定子列的每一行中的第一个非NA
列,并将此值复制到列x
。
实施基于this solution。它包括一些可靠的检查。
na.locl <- function(var, dt) {
checkmate::assert_data_table(dt)
checkmate::assert_string(var)
checkmate::assert_choice(var, names(dt))
ans_val = rep_len(NA_real_, nrow(dt))
selected_cols <- unlist(lapply(
var, function(x) stringr::str_subset(names(dt), paste0("^", x, "(_\\d*)?$"))))
for(col in selected_cols) {
i = is.na(ans_val) & (!is.na(dt[[col]]))
ans_val[i] = dt[[col]][i]
}
set(DT, , var, ans_val)
return(invisible(NULL))
}
此外,OP已要求对其他变量重复此操作。这可以使用lapply()
函数na.locl()
来完成。为了证明这一点,需要样本数据。
library(data.table)
DT0 <- data.table(y=c("a",NA,NA,NA), y_1=c(NA,3,NA,NA), y_2=c(1,NA,3,NA), y_3=c(1,1,1,NA))
DT <- cbind(DT0, setnames(copy(DT0), stringr::str_replace(names(DT0), "^y", "x")))
DT <- cbind(DT, setnames(copy(DT0), stringr::str_replace(names(DT0), "^y", "zzz")))
DT
# y y_1 y_2 y_3 x x_1 x_2 x_3 zzz zzz_1 zzz_2 zzz_3
#1: a NA 1 1 a NA 1 1 a NA 1 1
#2: NA 3 NA 1 NA 3 NA 1 NA 3 NA 1
#3: NA NA 3 1 NA NA 3 1 NA NA 3 1
#4: NA NA NA NA NA NA NA NA NA NA NA NA
除第1行外, y
,x
和zzz
为NA
。在DT上应用该功能后
dummy <- lapply(c("x", "y", "zzz"), na.locl, dt = DT)
DT
# y y_1 y_2 y_3 x x_1 x_2 x_3 zzz zzz_1 zzz_2 zzz_3
#1: a NA 1 1 a NA 1 1 a NA 1 1
#2: 3 3 NA 1 3 3 NA 1 3 3 NA 1
#3: 3 NA 3 1 3 NA 3 1 3 NA 3 1
#4: NA NA NA NA NA NA NA NA NA NA NA NA
列y
,x
和zzz
中的缺失值已替换为右侧的下一个非NA
值(如果在列的子集中可用) 。因此,第4行全部为NA
,因为在每个列子集中都没有非NA
(连续三个否定)。