用于在现有数据框中粘贴更正值的函数
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 进行排序,并将该列标记为 已排序 (通过设置属性 sorted)by 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
RHS
上 D2
对应列的列表(data.frame 也是一个列表)。
D1
现在将 就地修改 。
HTH
下面的 '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 进行排序,并将该列标记为 已排序 (通过设置属性 sorted)by reference。这允许我们使用二进制搜索执行连接。x[i]
in data.table 执行连接。您可以阅读更多相关信息 here。简而言之,对于D2
中列k
的每一行,它通过匹配D1
的键列(此处k
找到D1
中匹配的行索引).x[i, LHS := RHS]
执行连接以查找匹配的行,LHS := RHS
部分 adds/updatesx
使用LHS
中指定的列以及RHS
中指定的值 通过引用 。LHS
应该是列名或数字的向量,RHS
应该是值列表。因此,
D1[D2, (cols) := D2[, cols]]
从D2
中找到D1
中与k=c(1,3,4)
匹配的行,并更新cols
中指定的列D,E,A
RHS
上D2
对应列的列表(data.frame 也是一个列表)。
D1
现在将 就地修改 。
HTH