我有一个数据帧,它是a、b和c在"双向"上的所有可能排列
df1<-data.frame("x"=c("a","a","b"),"y"=c("b","c","c"),"A"=1:3 ,"B"=4:6,"C"=0,"T"=10:12)
df2<-data.frame("x"=df1$y,"y"=df1$x, "A"=df1$A,"B"=df1$B,"C"=df1$C,"T"=df1$T)
df<-rbind(df1,df2)
x y A B C T
1 a b 1 4 0 10
2 a c 2 5 0 11
3 b c 3 6 0 12
4 b a 1 4 0 10
5 c a 2 5 0 11
6 c b 3 6 0 12
我想用它来填充第二个空的数据帧
empty<-data.frame("x"=c("a","c"),"y"=c("b","a"),"A"=0,"T"=0)
x y A T
1 a b 0 0
2 c a 0 0
从而产生:
filled<-data.frame("x"=c("a","c"),"y"=c("b","a"),"A"=1:2,"T"=10:11)
x y A T
1 a b 1 10
2 c a 2 11
我尝试了一个没有运气的for循环
for(i in 1:nrow(empty)
{
if("x" == df$x && "y" == df$y)
{
empty[i,"A"]<-df$A
empty[i,"T"]<-df$T
}
}
以及上一篇文章中关于填充矩阵但没有成功的答案。如有任何建议,不胜感激。
您可以使用merge
:
merge(df[c("x","y","A","T")], empty[c("x","y")])
# x y A T
# 1 a b 1 10
# 2 c a 2 11
正如@mrdwab所指出的,您不需要创建一个empty
数据帧来保存最终数据。相反,让merge
为您做这件事。你所需要的只是一个数据帧,它包含你想要提取的(x,y)
对的组合:
extract.keys <- data.frame(x = c("a","c"), y = c("b","a"))
merge(df[c("x","y","A","T")], extract.keys)
把我的评论移到"答案"上,我不确定这最终的目标是什么。对我来说,即使添加了排列的概念,这似乎也是一个子集的问题。也就是说,如果关于如何创建"empty
"data.frame
的先验知识已经存在,我们可以简单地跳过创建该对象并必须合并的步骤,直接进行子集。
假设a
和b
将给出六个置换作为变量x
和y
,并且知道我们只对组合a+b
和c+a
感兴趣,我们可以在列x
和y
上使用paste0()
进行测试。
使用更新问题中的df
:
df[paste0(df$x, df$y) %in% c("ab", "ca"),
names(df) %in% c("x", "y", "A", "T")]
# x y A T
# 1 a b 1 10
# 5 c a 2 11
当然,@flodel的答案很好,但我只是很困惑,当按列和行索引进行子集设置就足够了时,为什么需要麻烦地创建一个空的data.frame
来填充。
更新
因为我还有其他应该做的工作,所以我决定做一些基准测试。结果如下:
library(rbenchmark)
benchmark(subsetting = df[paste0(df$x, df$y) %in% c("ab", "ca"),
names(df) %in% c("x", "y", "A", "T")],
merge.keys = merge(df[c("x","y","A","T")],
data.frame(x = c("a","c"),
y = c("b","a"))),
merge.empty = merge(df[c("x","y","A","T")], empty),
columns = c("test", "replications", "elapsed",
"relative", "user.self"))
# test replications elapsed relative user.self
# 3 merge.empty 100 0.321 6.294118 0.324
# 2 merge.keys 100 0.387 7.588235 0.384
# 1 subsetting 100 0.051 1.000000 0.048