这是在这里回答另一个问题。当您rbind
两个数据框时,它按名称而不是索引匹配列,这可能会导致意外行为:
> df<-data.frame(x=1:2,y=3:4)
> df
x y
1 1 3
2 2 4
> rbind(df,df[,2:1])
x y
1 1 3
2 2 4
3 1 3
4 2 4
当然,有一些解决方法。例如:
rbind(df,rename(df[,2:1],names(df)))
data.frame(rbind(as.matrix(df),as.matrix(df[,2:1])))
在编辑时:来自rename
包的plyr
实际上并不是这样工作的(尽管我认为我最初写这篇文章的时候它已经工作了......)。通过重命名的方法是使用SimonO101的解决方案:
rbind(df,setNames(df[,2:1],names(df)))
另外,也许令人惊讶的是,
data.frame(rbindlist(list(df,df[,2:1])))
按索引工作(如果我们不介意数据表,那么它非常简洁),所以这是do.call(rbind)
之间的区别。
问题是,rbind
两个名称不匹配的数据框的最简洁方法是什么?我知道这似乎微不足道,但这种事情最终会使代码混乱。而且我不想写一个名为rbindByIndex
的新函数。理想情况下,它会像rbind(df,df[,2:1],byIndex=T)
。
答案 0 :(得分:44)
您可能会在这里找到setNames
...
rbind(df, setNames(rev(df), names(df)))
# x y
#1 1 3
#2 2 4
#3 3 1
#4 4 2
我怀疑你的真实用例有点复杂。您当然可以根据需要在setNames
的第一个参数中重新排序列,只需在第二个参数中使用names(df)
,以便重新排序的列的名称与原始列匹配。
答案 1 :(得分:8)
这看起来很简单:
mapply(c,df,df[,2:1])
x y
[1,] 1 3
[2,] 2 4
[3,] 3 1
[4,] 4 2
对于这个简单的情况,你必须把它变回数据帧(因为mapply
将它简化为矩阵):
as.data.frame(mapply(c,df,df[,2:1]))
x y
1 1 3
2 2 4
3 3 1
4 4 2
重要提示1 :当您的数据框包含不同类型的向量时,类型强制似乎存在缺点:
df<-data.frame(x=1:2,y=3:4,z=c('a','b'))
mapply(c,df,df[,c(2:1,3)])
x y z
[1,] 1 3 2
[2,] 2 4 1
[3,] 3 1 2
[4,] 4 2 1
重要提示2 :如果你有因素,这也很糟糕。
df<-data.frame(x=factor(1:2),y=factor(3:4))
mapply(c,df[,1:2],df[,2:1])
x y
[1,] 1 1
[2,] 2 2
[3,] 1 1
[4,] 2 2
所以,只要您拥有所有数字数据,就没关系。