2016-02-05 22 views
7

Rでこれを行う方法stringsplit()ダッシュで区切られた名字が残っていない場合、分割を中止します。結果に示されているように、右側の部分文字列を保持します。R文字列を分割し、一致する部分文字列を右手に保持しますか?

a <- c("tim/tom meyer XY900 123kncjd", "sepp/max/peter moser VK123 456xyz") 

# result: 
c("tim meyer XY900 123kncjd", "tom meyer XY900 123kncjd", "sepp moser VK123 456xyz", "max moser VK123 456xyz", "peter moser VK123 456xyz") 

答えて

5

はここで異なる基本文字列関数のいくつかを使用して1つの可能性です。

## get the lengths of the output for each first name 
len <- lengths(gregexpr("/", sub(" .*", "", a), fixed = TRUE)) + 1L 
## extract all the first names 
## using the fact that they all end at the first space character 
fn <- scan(text = a, sep = "/", what = "", comment.char = " ") 
## paste them together 
paste0(fn, rep(regmatches(a, regexpr(" .*", a)), len)) 
# [1] "tim meyer XY900 123kncjd" "tom meyer XY900 123kncjd" 
# [3] "sepp moser VK123 456xyz" "max moser VK123 456xyz" 
# [5] "peter moser VK123 456xyz" 

追加:ここで少しのコードを使用して、第二の可能性です。もう少し早くなるかもしれない。

s <- strsplit(a, "\\/|(.*)") 
paste0(unlist(s), rep(regmatches(a, regexpr(" .*", a)), lengths(s))) 
# [1] "tim meyer XY900 123kncjd" "tom meyer XY900 123kncjd" 
# [3] "sepp moser VK123 456xyz" "max moser VK123 456xyz" 
# [5] "peter moser VK123 456xyz" 
+1

完璧! .. no loopと基底関数はまさに私が後に行ったものです) – Kay

+1

Nice solution Richard –

+0

その第2の解決策はお金の男1プラスです –

2

私は(stringiで)そのようにそれを行うだろう:

library("stringi") 

a <- c("tim/tom meyer XY900 123kncjd", "sepp/max/peter moser VK123 456xyz") 

stri_split_fixed(stri_match_first_regex(a, "(.+?)[ ]")[,2], "/") -> start 
stri_match_first_regex(a, "[ ](.+)")[,2] -> end 


for(i in 1:length(end)){ 
    start[[i]] <- paste(start[[i]], end[i]) 
} 

unlist(start) 

## [1] "tim meyer XY900 123kncjd" "tom meyer XY900 123kncjd" "sepp moser VK123 456xyz" 
## [4] "max moser VK123 456xyz" "peter moser VK123 456xyz" 
1

は、ここに1つのアプローチです:

a <- c('tim/tom meyer XY900 123kncjd','sepp/max/peter moser VK123 456xyz'); 
do.call(c,lapply(strsplit(a,' '),function(w) apply(expand.grid(strsplit(w,'/')),1,paste,collapse=' '))); 
## [1] "tim meyer XY900 123kncjd" "tom meyer XY900 123kncjd" "sepp moser VK123 456xyz" "max moser VK123 456xyz" "peter moser VK123 456xyz" 

このソリューションの利点は、それが適切に完全なデカルトを返す、というだけの最初の単語よりも、各文字列内のすべての単語のための分割および再結合を行うものです

a <- c('a/b/c d/e/f g/h/i','j/k/l m/n/o p/q/r'); 
do.call(c,lapply(strsplit(a,' '),function(w) apply(expand.grid(strsplit(w,'/')),1,paste,collapse=' '))); 
## [1] "a d g" "b d g" "c d g" "a e g" "b e g" "c e g" "a f g" "b f g" "c f g" "a d h" "b d h" "c d h" "a e h" "b e h" "c e h" "a f h" "b f h" "c f h" "a d i" "b d i" "c d i" "a e i" "b e i" "c e i" "a f i" "b f i" "c f i" "j m p" "k m p" "l m p" "j n p" "k n p" "l n p" "j o p" "k o p" "l o p" "j m q" "k m q" "l m q" "j n q" "k n q" "l n q" "j o q" "k o q" "l o q" "j m r" "k m r" "l m r" "j n r" "k n r" "l n r" "j o r" "k o r" "l o r" 
2

Rソリューションにはさまざまな方法があることを示すもう1つのアプローチはありません。文字列を/シンボルで分割します。残りの文字列から最初の名前を区切ります。次にpasteと組み合わせてください。面白い質問btw:

unlist(sapply(strsplit(a, "/"), function(x) {len <- length(x) 
    last <- gsub("^(\\w+).*", "\\1", x[len]) 
    fill <- gsub("^\\w+ ", "", x[len]) 
    paste(c(x[-len], last), fill)})) 
# [1] "tim meyer XY900 123kncjd" "tom meyer XY900 123kncjd" "sepp moser VK123 456xyz" 
# [4] "max moser VK123 456xyz" "peter moser VK123 456xyz" 
関連する問題