2011-11-28 14 views
20

文字列(人の名前)のベクトルを2つの列(ベクトル)に分割したいと思います。問題は、いくつかの人々が2つの単語の姓を持っているということです。私は最初と最後の2つの列に名前を分割したいと思います。下のコードを使って名前を決めることができますが、最後の名前はわかりません。 (フォードが一緒に保たなければならないPantera Lの「名字」を持っているという考えを得るために、下のサンプルセットのobs 29を見てください)最初のスペースに文字列を分割する

これまで何をしようとしていますか?

私はそれがどのように見えるしたいのですがどのような
x<-rownames(mtcars) 
unlist(strsplit(x, " .*")) 

:あなたは、パターンやグループのマッチングを行うことができる場合、私は(未テスト)このような何かを試してみた

  MANUF  MAKE 
27   Porsche  914-2 
28   Lotus  Europa 
29   Ford  Pantera L 
30   Ferrari  Dino 
31   Maserati Bora 
32   Volvo  142E 

答えて

25

正規表現rexpは、文字列の先頭の単語、オプションのスペース、および残りの文字列と一致します。かっこは、後方参照\\1\\2としてアクセスされるサブ式です。私にとって

rexp <- "^(\\w+)\\s?(.*)$" 
y <- data.frame(MANUF=sub(rexp,"\\1",x), MAKE=sub(rexp,"\\2",x)) 
tail(y) 
#  MANUF  MAKE 
# 27 Porsche  914-2 
# 28 Lotus Europa 
# 29  Ford Pantera L 
# 30 Ferrari  Dino 
# 31 Maserati  Bora 
# 32 Volvo  142E 
+0

@ Joshua Ullrich美しい。説明してくれてありがとう。 –

0

\s+(.*)\s+(.*) 
+4

ちょうどあなたが知っているように、正規表現のRは少し違っています。少なくとも、エラーを避けるために、各sの前に別の\を追加する必要があります。 – joran

0

[^\s]+を検索するとうまくいくと思います。テストされていない。

17

reshape2パッケージでハドレーのcolsplit機能は、この目的のために最も直感的です。 Joshuaの方法はより一般的です(つまり、正規表現が使用できる場所であればどこでも使用できます)。柔軟性があります(仕様を変更したい場合)。 stringrから

str_splitはスプリットを処理しますが、のようなさまざまな形式(リスト、それを返します。それを行うためのさらに別の方法

library(reshape2) 
y <- colsplit(x," ",c("MANUF","MAKE")) 
tail(y) 
#  MANUF  MAKE 
#27 Porsche  914-2 
#28 Lotus Europa 
#29  Ford Pantera L 
#30 Ferrari  Dino 
#31 Maserati  Bora 
#32 Volvo  142E 
+0

列分割を非常に使いやすくしました。ありがとう。 –

+0

+1本当に面白いですが、私は 'colsplit'がこの場合に3列以上を返すと仮定していたからです。私は間違っていた。 – Andrie

7

:しかしcolsplit関数は、この特定の設定に最適ですstrsplit)。しかし、正しい形式に操作するのは簡単です。

library(stringr) 
split_x <- str_split(x, " ", 2) 
(y <- data.frame(
    MANUF = sapply(split_x, head, n = 1), 
    MAKE = sapply(split_x, tail, n = 1) 
)) 

あるいは、ハドレーはstr_split_fixedと、コメントで述べたように。

1)をstrsplit:

y <- as.data.frame(str_split_fixed(x, " ", 2)) 
colnames(y) <- c("MANUF", "MAKE") 
y 
+0

@Riche Hadley Wickhamパッケージによるさらに別のソリューション。お返事ありがとうございます –

+2

'str_split_fixed'を使用する方が良いでしょう – hadley

+1

' colsplit'は 'str_split_fixed'を使用しているので、この答え+ hadleyのコメントは' colsplit'ソリューションに関連しています。 –

11

は、ここでは、2つのアプローチです。このアプローチでは、Rのコアにある関数のみを使用し、複雑な正規表現は使用しません。 2列の行列にそれをセミコロンで最初のスペースを置き換える(subを使用しないgsub)、strsplitセミコロンで、次いでrbind:ここ strapply gsubfnパッケージに

mat <- do.call("rbind", strsplit(sub(" ", ";", x), ";")) 
colnames(mat) <- c("MANUF", "MAKE") 

2)は一つでありますgsubfnパッケージにstrapplyを使用しています。正規表現の2つのカッコで囲まれた部分は、それぞれ目的の第1列と第2列を取得し、関数(式の表記で指定されています - これはfunction(x, y) c(MANUF = x, MAKE = y)と同じです)がそれらを取得して名前を追加します。simplify=rbind引数は、以前の解決法のように行列に変換するために使用されます。

library(gsubfn) 
mat <- strapply(x, "(\\S+)\\s+(.*)", ~ c(MANUF = x, MAKE = y), simplify = rbind) 

注:"character"マトリックス、matが、返されるいずれの場合においても"character"列のデータフレームを希望する場合は、これを追加します。"factor"列が求められていた場合

DF <- as.data.frame(mat, stringsAsFactors = FALSE) 

stringsAsFactors引数を省略します。

+0

私はちょうどここに戻りました。私は実際にあなたの#1のソリューションが供給されたものの中で最高のものを好んでいました。お返事ありがとうございました。 –

関連する問題