我有一个数据框,其中包含从具有独立变量A和B的实验中读取的值,该实验未涵盖A和B的所有可能的排列。我需要创建一个包含所有排列的数据框,其中为零数据中不存在特定值对的那些地方。
要创建一些示例数据,
interactions <- unique(data.frame(A = sample(1:5, 10, replace=TRUE),
B = sample(1:5, 10, replace=TRUE)))
interactions <- interactions[interactions$A < interactions$B, ]
interactions$val <- runif(nrow(interactions))
possible.interactions <- data.frame(t(combn(1:5, 2)))
names(possible.interactions) <- c('A', 'B')
创建
interactions
A B val
1 5 0.6881106
1 2 0.5286560
2 4 0.5026426
和
possible.interactions
A B
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
我要输出
A B val
1 2 NA
1 3 0.5286560
1 4 NA
1 5 0.6881106
2 3 NA
2 4 0.5026426
2 5 NA
3 4 NA
3 5 NA
4 5 NA
最快的方法是什么?
答案 0 :(得分:3)
这是一个基本解决方案,比merge
快得多(~10x):
possible.interactions$val <- interactions$val[
match(
do.call(paste, possible.interactions),
do.call(paste, interactions[1:2])
) ]
这会产生(注意,与你没有设定种子的b / c不同):
# A B val
# 1 1 2 0.59809242
# 2 1 3 0.92861520
# 3 1 4 0.64279549
# 4 1 5 NA
# 5 2 3 0.03554058
# 6 2 4 NA
# 7 2 5 NA
# 8 3 4 NA
# 9 3 5 NA
# 10 4 5 NA
这假设A&amp; B不包含空格,interactions
没有重复A-B
对(总是与第一对匹配)。
data.table
版本:
possible.DT <- data.table(possible.interactions)
DT <- data.table(interactions, key=c("A", "B"))
DT[possible.DT]
虽然只有在你的桌子很大或者你有data.table
的其他好处的用途时,这才有价值。如果你包括创建和键入表的开销,我发现在简单的情况下速度可以与match
相媲美。我确信有些情况下data.table
要快得多,特别是如果你按一次键然后再使用那个键。
为了完整性,这里是merge
版本:
merge(possible.interactions, interactions, all.x=T)
答案 1 :(得分:0)
如果订单对您很重要,我建议您使用join
包中的plyr
。与merge
相反,library(plyr)
join(interactions,possible.interactions,type="right")
Joining by: A, B
A B val
1 1 2 NA
2 1 3 NA
3 1 4 0.007602083
4 1 5 0.853415110
5 2 3 NA
6 2 4 0.321098658
7 2 5 NA
8 3 4 NA
9 3 5 NA
10 4 5 NA
在有不匹配的元素时不提供直观的排序。
{{1}}