用于在现有数据框中粘贴更正值的函数

Function for pasting corrected values inside existing dataframe

下面的 'paste_over' 函数之类的东西是否已经存在于基础 R 或标准 R 包之一中?

paste_over <- function(original, corrected, key){
  corrected <- corrected[order(corrected[[key]]),]

  output <- original
  output[
    original[[key]] %in% corrected[[key]],
    names(corrected)
    ] <- corrected

  return(output)
}

一个例子:

D1 <- data.frame(
  k = 1:5,
  A = runif(5),
  B = runif(5),
  C = runif(5),
  D = runif(5),
  E = runif(5)
  )

D2 <- data.frame(
  k=c(4,1,3),
  D=runif(3),
  E=runif(3),
  A=runif(3)
  )

D2 <- D2[order(D2$k),]

D3 <- D1
D3[
  D1$k %in% D2$k,
  names(D2)
  ] <- D2


D4 <- paste_over(D1, D2, "k")

all(D4==D3)

在示例中,D2 包含一些我想粘贴到 D1 中相应单元格的值。但是,D2 与 D1 的顺序不同,并且维度不同。

这样做的动机是,我得到了一个非常大的数据集,报告了其中的一些错误,并收到了原始数据集的一个子集,其中包含一些更正值。我希望能够 'paste over' 将新的、更正后的值添加到旧数据集中,而无需在结构方面更改旧数据集。 (因为我编写的其余代码假设是旧数据集的结构。)

虽然 paste_over 函数似乎可以工作,但我不禁认为这个问题之前一定已经解决了,所以也许已经有一个众所周知的函数,它既更快又具有错误检查功能。如果有那么请告诉我它是什么。 谢谢

您可以在您的函数中使用数据框的替换方法,就像这样。它为您做了足够的检查。我选择将逻辑行子集作为参数传递,但您可以更改它

pasteOver <- function(original, corrected, key) {
    "[<-.data.frame"(original, key, names(corrected), corrected)
}

(p1 <- pasteOver(D1, D2, D1$k %in% D2$k))
  k          A           B         C         D          E
1 1 0.18827167 0.006275082 0.3754535 0.8690591 0.73774065
2 2 0.54335829 0.122160101 0.6213813 0.9931259 0.38941407
3 3 0.62946977 0.323090601 0.4464805 0.5069766 0.41443988
4 4 0.66155954 0.201218532 0.1345516 0.2990733 0.05296677
5 5 0.09400961 0.087096652 0.2327039 0.7268058 0.63687025

p2 <- paste_over(D1, D2, "k")
identical(p1, p2)
# [1] TRUE

我们可以使用 data.table 完成此操作,如下所示:

setkeyv(setDT(D1), "k")
cols = c("D", "E", "A")
D1[D2, (cols) := D2[, cols]]
  • setDT() 通过引用 将 data.frame 转换为 data.table (实际上没有复制数据)。我们希望 D1 成为 data.table.

  • setkey() 按指定列(此处为 k)对 data.table 进行排序,并将该列标记为 已排序 (通过设置属性 sortedby reference。这允许我们使用二进制搜索执行连接。

  • x[i] in data.table 执行连接。您可以阅读更多相关信息 here。简而言之,对于 D2 中列 k 的每一行,它通过匹配 D1 的键列(此处 k 找到 D1 中匹配的行索引).

  • x[i, LHS := RHS] 执行连接以查找匹配的行,LHS := RHS 部分 adds/updates x 使用 LHS 中指定的列以及 RHS 中指定的值 通过引用 LHS 应该是列名或数字的向量,RHS 应该是值列表。

    因此,D1[D2, (cols) := D2[, cols]]D2 中找到 D1 中与 k=c(1,3,4) 匹配的行,并更新 cols 中指定的列 D,E,A RHSD2 对应列的列表(data.frame 也是一个列表)。

D1 现在将 就地修改

HTH