【问题标题】:Filling one data frame of permutations using another in r在 r 中使用另一个排列填充一个数据帧
【发布时间】:2012-08-18 12:58:35
【问题描述】:

我有一个数据框,它是“两个方向”上 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
    }
}

还有来自previous post 的关于填充矩阵但没有成功的答案。非常感谢任何建议。

【问题讨论】:

  • 您真的需要这样做吗?你不能把你原来的df子集化吗?
  • 我不认为我可以对排列问题进行子集化处理
  • 你到底在“置换”什么?这样的解决方案有什么问题df[1:2, c(1, 2, 3, 6)](行和列号的基本子集)或df[df$x=="a" | df$x=="b", names(df) %in% c("x", "y", "A", "T")],或者更好的是df[df$x %in% c("a", "b"), names(df) %in% c("x", "y", "A", "T")](行和列的匹配值的子集)?
  • 我调整了问题以反映我所说的排列的意思......我尝试了你的建议,但无法让它发挥作用......现在问题可能更清楚一点,还有任何其他建议?

标签: r if-statement for-loop dataframe


【解决方案1】:

你可以使用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 为您做这件事。您所需要的只是一个 data.frame,其中包含您要提取的 (x,y) 对的组合:

extract.keys <- data.frame(x = c("a","c"), y = c("b","a"))
merge(df[c("x","y","A","T")], extract.keys)

【讨论】:

  • 我试过了,但它不适用于真实数据。我已经调整了问题以更准确地反映真实数据框。感谢您的回答,很抱歉可能没有解释我第一次真正想做的事情....
  • @Elizabeth,请再次更新问题。就目前而言,弗洛德尔的回答仍然可以正常工作。
【解决方案2】:

将我的 cmets 移至“答案”,我不确定最终目标是什么。对我来说,即使添加了排列的概念,这似乎也是一个子集的问题。也就是说,如果已经有关于如何创建“emptydata.frame的先验知识,我们可以简单地跳过创建该对象和必须合并的步骤,直接子集。

鉴于ab 将给出六个排列作为变量xy,并且知道我们只对a+bc+a 的组合感兴趣,我们可以轻松使用paste0()在要测试的列 xy 上。

使用更新问题中的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

【讨论】:

  • 谢谢,这真的很有帮助,我学到了一些新东西......基准!再次感谢。
猜你喜欢
  • 2021-12-25
  • 1970-01-01
  • 2019-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-02
  • 2021-01-08
  • 2016-09-15
相关资源
最近更新 更多