web-dev-qa-db-ja.com

列名を無視するようにrbindを取得する最も簡単な方法

これは、ここでの別の質問への回答として出てきました。 2つのデータフレームを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)の違いです。

問題は、名前が一致しない2つのデータフレームをrbindする最も簡潔な方法は何ですか?これは些細なことのように思えますが、この種のことはコードを混乱させることになります。そして、rbindByIndexという新しい関数を書く必要はありません。理想的には、rbind(df,df[,2:1],byIndex=T)のようなものになります。

40
mrip

ここでsetNamesが便利かもしれません...

_rbind(df, setNames(rev(df), names(df)))
#  x y
#1 1 3
#2 2 4
#3 3 1
#4 4 2
_

実際のユースケースはやや複雑だと思います。もちろん、setNamesの最初の引数で列を並べ替えることができます。2番目の引数でnames(df)を使用するだけで、並べ替えられた列の名前が元の列と一致します。

45
Simon O'Hanlon

これは非常に簡単なようです:

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

したがって、すべての数値データがあれば大丈夫です。

8
Thomas