gpt4 book ai didi

r - 通过匹配它们的列来合并具有不同大小的两个数据框

转载 作者:行者123 更新时间:2023-12-04 10:45:22 25 4
gpt4 key购买 nike

如果列 X 和 Y 相等(我必须匹配 dOne.X == dTwo.X & dOne.Y == dTwo.YdOne.X == dTwo.Y & dOne.Y == dTwo.X ),我正在尝试“合并”另一个数据帧的列 V
我使用 for 解决了这个问题循环,但是当数据帧 dOne 很大时它很慢(在我的机器上,如果 length(dOne.X) == 500000 需要 25 分钟)。我想知道是否有办法使用更快的“矢量化”操作来解决这个问题。以上是我想做的一个例子:

Data Frame ONE
X Y V
a b 2
a c 3
a d 0
a e 0
b c 2
b d 3
b e 0
c d 2
c e 0
d e 0

Data Frame TWO
X Y V
a b 1
a c 1
a d 1
b c 1
b d 1
c d 1
e d 1

Expected Data Frame after the columns are merged
X Y V V2
a b 2 1
a c 3 1
a d 0 1
a e 0 0
b c 2 1
b d 3 1
b e 0 0
c d 2 1
c e 0 0
d e 0 1

这是我到目前为止使用的代码,当 dOne 很大(数十万或行)时它很慢:
copyadjlistValueColumn <- function(dOne, dTwo) {
dOne$V2 <- 0

lv <- union(levels(dOne$Y), levels(dOne$X))

dTwo$X <- factor(dTwo$X, levels = lv)
dTwo$Y <- factor(dTwo$Y, levels = lv)
dOne$X <- factor(dOne$X, levels = lv)
dOne$Y <- factor(dOne$Y, levels = lv)

for(i in 1:nrow(dTwo)) {
row <- dTwo[i,]
dOne$V2[dOne$X == row$X & dOne$Y == row$Y] <- row$V
dOne$V2[dOne$X == row$Y & dOne$Y == row$X] <- row$V
}
dOne
}

这是一个 testthat 测试用例,涵盖了我的期望(使用上面的数据框):
test_that("Copy V column to another Data Frame", {
dfOne <- data.frame(X=c("a", "a", "a", "a", "b", "b", "b", "c", "c", "d"),
Y=c("b", "c", "d", "e", "c", "d", "e", "d", "e", "e"),
V=c(2, 3, 0, 0, 2, 3, 0, 2, 0, 0))

dfTwo <- data.frame(X=c("a", "a", "a", "b", "b", "c", "e"),
Y=c("b", "c", "d", "c", "d", "d", "d"),
V=c(1, 1, 1, 1, 1, 1, 1))

lv <- union(levels(dfTwo$Y), levels(dfTwo$X))
dfExpected <- data.frame(X=c("a", "a", "a", "a", "b", "b", "b", "c", "c", "d"),
Y=c("b", "c", "d", "e", "c", "d", "e", "d", "e", "e"),
V=c(2, 3, 0, 0, 2, 3, 0, 2, 0, 0),
V2=c(1, 1, 1, 0, 1, 1, 0, 1, 0, 1))
dfExpected$X <- factor(dfExpected$X, levels = lv)
dfExpected$Y <- factor(dfExpected$Y, levels = lv)

dfMerged <- copyadjlistValueColumn(dfOne, dfTwo)

expect_identical(dfMerged, dfExpected)
})

有什么建议吗?

非常感谢 :)

最佳答案

这是一个可能的 data.table包方法。对于像您这样的大数据集,这种方法应该特别有效:

先转换成data.table对象并添加键

library(data.table)
setkey(setDT(dfOne), X, Y)
setkey(setDT(dfTwo), X, Y)

然后在 X & Y 上执行连接组合 - 通过匹配键列执行连接 X,YdfOne带键列 X,YdfTwo分别。
dfOne[dfTwo, V2 := i.V]

现在在 Y & X 上执行连接组合 - 通过匹配键列执行连接 X,YdfOne带键列 Y,XdfTwo分别。
setkey(dfTwo, Y, X)
dfOne[dfTwo, V2 := i.V][]

结果(我将不匹配的保留为 NA s 而不是零,因为这样更有意义):
#     X Y V V2
# 1: a b 2 1
# 2: a c 3 1
# 3: a d 0 1
# 4: a e 0 NA
# 5: b c 2 1
# 6: b d 3 1
# 7: b e 0 NA
# 8: c d 2 1
# 9: c e 0 NA
# 10: d e 0 1

关于r - 通过匹配它们的列来合并具有不同大小的两个数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27105686/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com