我的数据包含因子lang
和alg
,我想比较所有lang
之间所选alg
对的差异:
> perf[perf$lang == "java", c("alg", "cpu")]
alg cpu
173 binarytrees 0.196
174 chameneosredux 0.404
175 fannkuchredux 0.648
> perf[perf$lang == "python3", c("alg", "cpu")]
alg cpu
246 binarytrees 0.972
248 fannkuchredux 13.752
249 fasta 1.152
对于binarytrees
我希望获得0.196/0.972
,但chameneosredux
为NA
,fannkuchredux
为0.648/13.752
,fasta
是} NA
,...
一种方法是对alg
上的行进行排序,但我不明白如何使用NA
为缺少的因素(unique(perf$alg)
中提供的所有因素)注入行。
更新尽管原始问题我认为我喜欢将两个数据帧的列组合到同一因素的单个数据帧中:
binarytrees 0.196 0.972
chameneosredux 0.404 NA
fasta NA 1.152
fannkuchredux 0.648 13.752
答案 0 :(得分:1)
您正在寻找的内容基本上是SQL中的FULL OUTER JOIN
,可以使用base::merge
使用all = TRUE
来完成。
以下是可比较的数据集:
Df <- data.frame(
Lang = rep(LETTERS[1:5], rep(3, 5)),
Alg = c(replicate(5, sample(letters[1:4], 3))),
Cpu = rnorm(15),
stringsAsFactors = FALSE
)
请注意,我使用stringsAsFactors = FALSE
。我建议您将列转换为character
向量;我没有看到在这里使用factor
的任何需要。
这是光包装函数中的merge
操作,只是为了使演示更清晰:
compare <- function(x, y, data) {
merge(x = data[data$Lang == x[1], 2:3],
y = data[data$Lang == y[1], 2:3],
by = "Alg", all = TRUE,
suffixes = c(paste0(".", x[1]),
paste0(".", y[1]))
)
}
这里正在使用:
compare("A", "D", Df)
# Alg Cpu.A Cpu.D
#1 a NA -0.06520117
#2 b 1.0587151 0.08379303
#3 c -2.0390119 NA
#4 d -0.8574474 1.27865596
compare("A", "C", Df)
# Alg Cpu.A Cpu.C
#1 b 1.0587151 -1.0230431
#2 c -2.0390119 -0.7691048
#3 d -0.8574474 -1.2421078
关于我的评论,也可以使用sqldf
来实现。 SQLite
不支持FULL OUTER JOIN
,但如果您对SQL感到满意,这不应该是一个问题,因为可能有十几种方法可以解决这个问题:
library(sqldf)
sqldf(
"select x.Alg
,lhs.Cpu as 'Cpu.A'
,rhs.Cpu as 'Cpu.D'
from (
select distinct d.Alg
from Df d
) x
left join Df lhs on lhs.Alg = x.Alg and lhs.Lang = 'A'
left join Df rhs on rhs.Alg = x.Alg and rhs.Lang = 'D'
order by x.Alg"
)
# Alg Cpu.A Cpu.D
#1 a NA -0.06520117
#2 b 1.0587151 0.08379303
#3 c -2.0390119 NA
#4 d -0.8574474 1.27865596