我有一个数据集看起来像

set.seed(18)
library(data.table)
site1 <- data.table(id = 1:10, A = c(sample(c(NA, letters[1:10]),10)),
                    B = sample(c(NA, LETTERS[1:7]), 10, replace = T),
                    C = sample(c(NA, 1:4), 10, replace = T))

site2 <- data.table(id = c(1:4, sample(5:15, 6)),
                    A = c(NA, NA, NA, sample(letters, 1), NA, NA, NA, sample(letters, 1), NA, NA),
                    B = sample(LETTERS, 10), d = sample(1:5, replace = T))

和一个看起来像
col.smash <- function(a, b, linkvars){
  require(data.table)
 
  ##### CONVERT TO DATA.TABLES FOR EASIER USE, AND MERGE
  if(dim(a)[1] <= dim(b)[1]){
    c <- data.table(a); setkeyv(c, linkvars)
    d <- data.table(b); setkeyv(d, linkvars)
  } else {
    c <- data.table(b); setkeyv(c, linkvars)
    d <- data.table(a); setkeyv(d, linkvars)
  }
 
  k <- c[d]
 
  rep.list<- names(a)[names(a) %in% names(b) & !(names(a) %in% linkvars)]
  i.combo <- paste0("i.",rep.list)

  f <- k[ , (rep.list) := lapply(.SD, function(x){ifelse(is.na(x),
                                                   get("i.", names(x)), x)}),
          .SDcols = rep.list]
  return(f)
  }

该函数的目的是查看site1site2中都包含哪些变量,如果其中包含“NA”,则说site1$A,将其替换为site2$A中的相应值。 site1相对于site2有一个层次结构,这就是为什么ifelse语句仅检查带有“NA”的变量的原因。

由于条件无法正常运行后,第一个lapply结果(ifelse)导致get("i.",names(x))函数出现错误。这样做时,出现以下错误:
Error in as.environment(pos) : using 'as.environment(NULL)' is defunct

我不明白。理想情况下,我会得到一个data.table,其中site1site2中的所有值都带有变量ABCD而不是i.Ai.B这样的变量,
    id  A  B  C  d
 1:  1  i  E NA  4
 2:  2  g  F NA  4
 3:  3  h NA  4  1
 4:  4  x  B  4  2
 5:  5  j  G NA  NA
 6:  6  c NA  3  4
 7:  7  a  D  2  NA
 8:  8  b NA  2  NA
 9:  9  d  G  1  4
10: 10  f NA  1  NA
11: 12 NA  V NA  2
12: 13  n  J NA  1
13: 14 NA  T NA  1
14: 15 NA  X NA  1

所以我认为我确实有两个问题。第一个是错误,第二个是我没有在函数中获得k中的所有行。他们似乎无关。

任何帮助表示赞赏。

此外,任何人只要能找到令人难以置信的 col.smash参考,即可获得布朗尼积分。

最佳答案

该函数的目的是查看site1site2中都包含哪些变量,如果其中包含“NA”,则说site1$A,将其替换为site2$A中的相应值。在site1之上有一个site2层次结构

输出可以像

g <- function(d1, d2, byvars){
  D = funion(d1[, ..byvars], d2[, ..byvars])

  d2vars = setdiff(names(d2), byvars)
  D[d2, on=byvars, (d2vars) := mget(sprintf("i.%s", d2vars))]

  d1vars = setdiff(names(d1), byvars)
  D[d1, on=byvars, (d1vars) := mget(sprintf("i.%s", d1vars))]

  setcolorder(D, c(byvars, d1vars, setdiff(d2vars, d1vars)))
  setorderv(D, byvars)[]
}

g(site1, site2, "id")

这使
    id  A  B  C  d
 1:  1  i  E NA  4
 2:  2  g  F NA  4
 3:  3  h NA  4  1
 4:  4 NA  B  4  2
 5:  5  j  G NA NA
 6:  6  c NA  3  4
 7:  7  a  D  2 NA
 8:  8  b NA  2 NA
 9:  9  d  G  1  4
10: 10  f NA  1 NA
11: 12 NA  V NA  2
12: 13  n  J NA  1
13: 14 NA  T NA  1
14: 15 NA  X NA  1

这个怎么运作
byvars参数允许使用列名称的向量。

相当新的..语法允许引用存储在data.table外部的列的索引。我查看了FAQ和?data.table,找不到任何文档。现在,它是the first changelog item in 1.10.2 at least

为了给出“site1相对于site2的层次结构”,我们首先从site2添加,然后再从site1添加,这样它将获得最后的编辑。
funion的使用假定每个表中没有重复项。如果有的话,将需要一种更复杂的方法来执行此步骤,可能类似于
D = rbind(d1[, ..byvars], d2[,..byvars][!d1, on=byvars])

关于r - 如何在data.table中动态使用lapply?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44557641/

10-11 16:30