3

次のような文字列のベクトルがあるとしましょう。

vectorOfStrings <- c("Name: Andrew, College: Bradford",
                     "Name: Charlie Daniels, College: Easton College",
                     "Name: Frank Gehry, III, College: Highlands University")

明確な繰り返しの「名前:」、「、大学:」パターンがあります。

次のようなリスト (または data.frame) を作成したいと思います。

listOfValues <- list(c("Andrew", "Charlie Daniels", "Frank Gehry, III"),
                     c("Bradford", "Easton College", "Highlands University"))

vectorOfStringsからに到達する最も簡単な方法は何listOfValuesですか? 私は、base文字列操作関数と にかなり精通していますstringrが、これは比較的一般的な状況であると考えており、比較的よく開発された解決策があることを望んでいます。

前もって感謝します。

4

5 に答える 5

4

考えられる解決策は次の 2 つです。

(1) strapplycこのmatステートメントは、最初の列に名前を保持し、2 番目の列に大学を保持する行列を作成します。次に、最後のステートメントでそれを名前のないリストに変換します。

library(gsubfn)

pat <- "Name: (.*), College: (.*)"
mat <- strapplyc(vectorOfStrings, pat, simplify = rbind)

unname(as.list(as.data.frame(mat, stringsAsFactors = FALSE)))

(2) gsub/read.table 単純な R のみを使用するバリエーションは、上記のgsubwithを使用しpatて、各入力文字列を、データを含むがタグを含まないパイプ区切りの文字列に変換することです。でそれを読むとread.table、データフレームが得られますDF。最後にDF、名前のないリストに変換します。

g <- gsub(pat, "\\1|\\2", vectorOfStrings)
DF <- read.table(text = g, sep = "|", as.is = TRUE)

unname(as.list(DF))

追加: 2 番目のソリューション

于 2013-02-26T01:50:23.673 に答える
3

私は数学的なコーヒーのアイデアが好きですが、私はすでにこれを書いているので、別の可能性があります:

X <- strsplit(vectorOfStrings, ",\\s*(?=College:)", perl=TRUE)
do.call(rbind, lapply(X, function(X) gsub("(Name|College):\\s*", "", X)))
#      [,1]               [,2]                  
# [1,] "Andrew"           "Bradford"            
# [2,] "Charlie Daniels"  "Easton College"      
# [3,] "Frank Gehry, III" "Highlands University"
于 2013-02-26T01:30:46.607 に答える
2
  do.call(rbind, strsplit(unlist(
            strsplit(vectorOfStrings, "Name: ")), ", College: "))

       [,1]               [,2]                  
  [1,] "Andrew"           "Bradford"            
  [2,] "Charlie Daniels"  "Easton College"      
  [3,] "Frank Gehry, III" "Highlands University"


すでに多くの良い答えがあるようです。@Josh O'Brien と同様に、strsplit を使用します。

"Name"と を保持していないので"College"、すぐに分割できます。次に、それを a にラップするだけでdo.call(rbind, ___) 、分割によって作成された空の文字列が自動的に削除されます。

于 2013-02-26T05:18:58.450 に答える
1

regexpを使用して、この種のことを行いますperl=T(それ以外の場合、キャプチャされたグループを抽出する良い方法は見つかりませんでした):

m <- regexpr('^Name: *(.+), *College: (.+) *$',
             vectorOfStrings, perl=T)
# m looks like this:
# [1] 1 1 1
# attr(,"match.length")
# [1] 31 46 53
# attr(,"useBytes")
# [1] TRUE
# attr(,"capture.start")  # one column per capturing bracket,   
# [1,] 7 24               # one row per entry in vectorOfStrings
# [2,] 7 33
# [3,] 7 34
# attr(,"capture.length")    
# [1,]  6  8
# [2,] 15 14
# [3,] 16 20
# attr(,"capture.names")
# [1] "" ""

# laziness
st <- attr(m, 'capture.start')
en <- st + attr(m, 'capture.length') - 1
numCaptures <- ncol(st)

matches <- sapply(1:numCaptures, function (i) {
    return(substr(vectorOfStrings, st[, i], en[, i]))
})

# matches
#     [,1]               [,2]                  
# [1,] "Andrew"           "Bradford"            
# [2,] "Charlie Daniels"  "Easton College"      
# [3,] "Frank Gehry, III" "Highlands University"

matches希望の形にマッサージします。かなり頻繁に使用するため、通常はこれを関数でラップします。

次のように Perl 命名正規表現を使用することもできます。

m <- regexpr('^Name: *(?<name>.+), *College: (?<college>.+) *$',
             vectorOfStrings, perl=T)

となり、またなりattr(m, 'capture.names')ます。c('name', 'college')colnames(attr(m, 'capture.(start or length)'))c('name', 'college')

とにかく、キーが を使用しているように見えるperl=Tか、regexprキャプチャブラケットごとに開始/終了ポイントのセットを返しません。

于 2013-02-26T01:23:51.917 に答える
1

おそらく後方参照を使用する方が簡単です

> vectorOfStrings
[1] "Name: Andrew, College: Bradford"                       "Name: Charlie Daniels, College: Easton College"       
[3] "Name: Frank Gehry, III, College: Highlands University"
> list(gsub('^Name:(.*), College:(.*)$',"\\1", vectorOfStrings) , gsub('^Name:(.*), College:(.*)$',"\\2", vectorOfStrings))
[[1]]
[1] " Andrew"           " Charlie Daniels"  " Frank Gehry, III"

[[2]]
[1] " Bradford"             " Easton College"       " Highlands University"
于 2013-02-26T01:36:32.117 に答える