下面的'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函数似乎工作,但我不禁认为这之前必须解决,所以也许已经有一个众所周知的函数,它既快又错误检查。如果有的话请告诉我它是什么。 感谢。
答案 0 :(得分:4)
我们可以使用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进行排序,并将该列标记为排序(通过设置属性已排序)引用。这允许我们使用二进制搜索来执行连接。
x[i]
执行连接。您可以阅读更多相关信息here。简而言之,对于k
中的D2
列中的每一行,它通过匹配D1
的关键列(此处为{{}来查找D1
中的匹配行索引1}})。
k
执行联接以查找匹配的行,x[i, LHS := RHS]
部分使用{{1}中指定的列添加/更新 LHS := RHS
使用引用在x
中指定的值。 LHS
应该是列名或数字的向量,RHS
应该是值列表。
因此,LHS
在RHS
中找到D1[D2, (cols) := D2[, cols]]
中与D1
匹配的行,并在列表中更新k=c(1,3,4)
中指定的列D2
(一个数据框也是一个列表)来自D,E,A
上cols
的相应列。
D2
现在将就地修改。
HTH
答案 1 :(得分:1)
您可以在函数中使用替换方法来处理数据框,也许这样。它会为你做足够的检查。我选择将逻辑行子集作为参数传递,但您可以更改
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