【问题标题】:How to access variables of datatable when passed as a parameter to a function?作为参数传递给函数时如何访问数据表的变量?
【发布时间】:2017-04-05 20:34:56
【问题描述】:

我是 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_1 中的值替换y 变量中的值,这些值是NA,如果它们不是NULL,或者替换为y_2 等等。像这样,我想创建一个可以接受不同变量但具有相同结尾的函数。

更新:Uwe,感谢您指出上一个问题。我发现它非常有用。但是,我的要求略有不同。我需要对其他变量以及值为 NA 的变量进行相同的更新。例如,我需要对 (x,x_1,x_2,x_3...),(z,z_1,z_2,z_3..) 和除 y 之外的一些其他变量执行此操作。有没有办法使用 lapply 或函数来做到这一点。

提前致谢。

【问题讨论】:

  • 您在问题中遗漏了一个重要部分,即如何使用您定义的DT 调用fun 函数。
  • 我想传递数据表和我想用它替换它的 NA 值的变量。就像 fun(DT,"y")
  • 这是同一个问题(忽略对 grep 列名的希望):stackoverflow.com/q/37776942 Alexis 的回答可能在这两者中更有效,fwiw。

标签: r data.table


【解决方案1】:

OP 正在寻找 locf 方法的变体(最后一次观察结转),例如实现为 zoo::na.locf()。虽然na.locf() 通常应用于 data.frame 的向量或列,但 OP 正在寻找应用于data.table 的每一行但仅限于特定列子集的变体。因此,该函数被命名为na.locl()(最后一次观察left)。

此外,data.table 将在原地更新,例如,无需复制。列以特定方式命名,例如,xx_1x_2x_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

yxzzz 除了第 1 行之外是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

yxzzz 列中的缺失值已替换为右侧的下一个非NA 值(如果在列子集中可用)。因此,第 4 行全是NA,因为在每个列子集中都没有非NA(即一行中的三个否定)可用。

【讨论】:

  • 谢谢 Uwe。我用你以前的帖子来完成我的工作。但我用样本测试数据测试了这个新功能,它工作了。我将使用此功能并更新我的代码。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2021-11-03
  • 2010-12-29
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多