データフレームで区切り文字に基づいて1つの列を2つに分割したいと思います。例えば、
a|b
b|c
になる
a b
b c
データフレーム内。
ありがとう!
@Taesung Shinは正しいですが、それからdata.frame
にするためのもう少しの魔法です。あいまいさを避けるために「x | y」行を追加しました。
df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
foo <- data.frame(do.call('rbind', strsplit(as.character(df$FOO),'|',fixed=TRUE)))
または、既存のdata.frameの列を置き換える場合:
within(df, FOO<-data.frame(do.call('rbind', strsplit(as.character(FOO), '|', fixed=TRUE))))
生成するもの:
ID FOO.X1 FOO.X2
1 11 a b
2 12 b c
3 13 x y
Hadleyは、関数reshape
を使用して、colsplit
パッケージのデータフレーム内でこれを行う非常にエレガントなソリューションを提供しています。
require(reshape)
> df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
> df
ID FOO
1 11 a|b
2 12 b|c
3 13 x|y
> df = transform(df, FOO = colsplit(FOO, split = "\\|", names = c('a', 'b')))
> df
ID FOO.a FOO.b
1 11 a b
2 12 b c
3 13 x y
新しく人気のあるtidyr
パッケージは、separate
でこれを行います。正規表現を使用するため、|
をエスケープする必要があります
df <- data.frame(ID=11:13, FOO=c('a|b', 'b|c', 'x|y'))
separate(data = df, col = FOO, into = c("left", "right"), sep = "\\|")
ID left right
1 11 a b
2 12 b c
3 13 x y
ただし、この場合、デフォルトは十分に機能します(分割する英数字以外の文字を探します)。
separate(data = df, col = FOO, into = c("left", "right"))
SOに関する最近の質問 にリンクされているため、この質問に出くわしました。
答えの恥知らずなプラグイン:「splitstackshape」パッケージのcSplit
を使用します。
df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
library(splitstackshape)
cSplit(df, "FOO", "|")
# ID FOO_1 FOO_2
# 1 11 a b
# 2 12 b c
# 3 13 x y
この特定の関数は、各列に異なる区切り文字がある場合でも、複数の列の分割も処理します。
df <- data.frame(ID=11:13,
FOO=c('a|b','b|c','x|y'),
BAR = c("A*B", "B*C", "C*D"))
cSplit(df, c("FOO", "BAR"), c("|", "*"))
# ID FOO_1 FOO_2 BAR_1 BAR_2
# 1 11 a b A B
# 2 12 b c B C
# 3 13 x y C D
基本的に、これは ベースRアプローチは次のとおりです。read.table(text = some_character_vector, sep = some_sep)
を使用し、その出力を元のdata.frame
にバインドするための派手な便利なラッパーです。つまり、別の
df <- data.frame(ID=11:13, FOO=c('a|b','b|c','x|y'))
cbind(df, read.table(text = as.character(df$FOO), sep = "|"))
ID FOO V1 V2
1 11 a|b a b
2 12 b|c b c
3 13 x|y x y
strsplit(c('a|b','b|c'),'|',fixed=TRUE)
@Ramnathと@Tommyの回答を組み合わせることで、1つ以上の列のベースRで機能するアプローチを見つけることができました。
基本的な使用法:
> df = data.frame(
+ id=1:3, foo=c('a|b','b|c','c|d'),
+ bar=c('p|q', 'r|s', 's|t'), stringsAsFactors=F)
> transform(df, test=do.call(rbind, strsplit(foo, '|', fixed=TRUE)), stringsAsFactors=F)
id foo bar test.1 test.2
1 1 a|b p|q a b
2 2 b|c r|s b c
3 3 c|d s|t c d
複数の列:
> transform(df, lapply(list(foo,bar),
+ function(x)do.call(rbind, strsplit(x, '|', fixed=TRUE))), stringsAsFactors=F)
id foo bar X1 X2 X1.1 X2.1
1 1 a|b p|q a b p q
2 2 b|c r|s b c r s
3 3 c|d s|t c d s t
複数の分割列の命名の改善:
> transform(df, lapply({l<-list(foo,bar);names(l)=c('foo','bar');l},
+ function(x)do.call(rbind, strsplit(x, '|', fixed=TRUE))), stringsAsFactors=F)
id foo bar foo.1 foo.2 bar.1 bar.2
1 1 a|b p|q a b p q
2 2 b|c r|s b c r s
3 3 c|d s|t c d s t