2016-05-17 7 views
1

ソースからオンラインでデータをスクラップして、個人に関する情報のn行のデータフレーム(df1)を作成しました。これは単一の文字列として提供され、単語を適切な列に分割します。値とシフトのデータフレームを置換する特定の条件が満たされている場合

情報の90%は、データフレーム(6)の適切な数の列に正しくフォーマットされますが、しばらくの間、余分な単語を含む行が文字列の先頭から4番目の単語。これらの行には7つの列があり、データフレーム内の他のすべての列からオフセットされています。ここ

は一例である:あなたがアイテム#10を添加し、余分な入力を有して見ることができる

Num Last-Name First-Name Cat. DOB Location 

11 Jackson, Adam L 1982-06-15 USA 
2 Pearl, Sam R 1986-11-04 UK 
5 Livingston, Steph LL 1983-12-12 USA 
7 Thornton, Mark LR 1982-03-26 USA 
10 Silver, John RED LL 1983-09-14 USA 


df1 = c(" 11 Jackson, Adam L 1982-06-15 USA", 
    "2 Pearl, Sam R 1986-11-04 UK", 
    "5 Livingston, Steph LL 1983-12-12 USA", 
    "7 Thornton, Mark LR 1982-03-26 USA", 
    "10 Silver, John RED LL 1983-09-14 USA") 

、色"RED"は、文字列の途中に挿入されます。

を使用して4番目の単語にいくつの文字が含まれているかを評価するコードを実行し始めました.3以上の場合(Cat.列の値は1〜2文字です)データフレームの最後に新しい列が作成され、値が割り当てられ、値がない場合(つまり、数値がFALSEと評価された場合)、NAと入力します。私はおそらくmutate(私の個人的な快適ゾーン)に大規模なネストされたifelse文を作成することができます確信しているが、私は私の望ましい結果を達成するために、より効率的な方法が存在する必要があります図:

Num Last-Name First-Name Cat. DOB Location Color 

11 Jackson, Adam L 1982-06-15 USA NA 
2 Pearl, Sam R 1986-11-04 UK NA 
5 Livingston, Steph LL 1983-12-12 USA NA 
7 Thornton, Mark LR 1982-03-26 USA NA 
10 Silver, John LL 1983-09-14 USA RED 

私がしたいです文字列の先頭から4番目の単語が3文字以上あるインスタンスを検索し、その単語または値をデータフレームの最後の新しい列に割り当て、その行の対応する値を適切に配置するために左にシフトします他の列のデータと一緒に使用します。

+0

あなたはそれがすべて大文字である任意の基準を持っていますか? – akrun

+0

@akrun大文字でなければならないという個人的な基準はありませんが、ソースから来るときは、文字列の先頭から4番目の値(分類カテゴリであっても、特定のインスタンスでは色)でもかまいません。どちらも大文字の値になります。 – wetcoaster

答えて

1

我々は

v1 <- gsub("([^,]+),(\\s+[[:alpha:]]+)\\s*\\S*(\\s+[[:alpha:]]+\\s+\\d{4}-\\d{2}-\\d{2}.*)", 
      "\\1\\2\\3", trimws(df1)) 
d1 <- read.table(text=v1, sep="", header=FALSE, stringsAsFactors=FALSE, 
col.names = c("Num", "LastName", "FirstName", "Cat", "DOB", "Location")) 
d1$Color <- trimws(gsub("^[^,]+,\\s+[[:alpha:]]+|[[:alpha:]]+\\s+\\d{4}-\\d{2}-\\d{2}\\s+\\S+$", 
         "", trimws(df1))) 
d1 
# Num LastName FirstName Cat  DOB Location Color 
#1 11 Jackson  Adam L 1982-06-15  USA  
#2 2  Pearl  Sam R 1986-11-04  UK  
#3 5 Livingston  Steph LL 1983-12-12  USA  
#4 7 Thornton  Mark LR 1982-03-26  USA  
#5 10  Silver  John LL 1983-09-14  USA RED 
+1

本当にうまくいっていますが、私はあなたの編集前にそれを知っていましたが、あなたが提供したコードの最初の行を利用することができました。さらに良い今 - ありがとう! – wetcoaster

2

がここにシンプルな方法です余分な部分文字列を削除するためにgsubを使用することができます。

input <- gsub("(.*, \\w+) ((?:\\w){3,})(.*)", "\\1 \\3 \\2", input, TRUE) 
input <- gsub("([0-9]\\s\\w+)\\n", "\\1 NA\n", input, TRUE) 

最初GSUBは、文字列の末尾に色を転置します。 2番目のgsubはに変更されていないの行には日付と国コード(国番号と色ではなく)で終わるようになり、単純に "NA"が追加されます。

IDEone demo

0

正規表現の代わりにstrsplitを使用する:

# split strings in df1 on commas and spaces not preceded by the start of the line 
s <- strsplit(df1, '(?<!^)[, ]+', perl = T) 

# iterate over s, transpose the result and make it a data.frame 
df2 <- data.frame(t(sapply(s, function(x){ 
    # if number of items in row is 6, insert NA, else rearrange 
    if (length(x) == 6) {c(x, NA)} else {x[c(1:3, 5:7, 4)]} 
}))) 

# add names 
names(df2) <- c("Num", "Last-Name", "First-Name", "Cat.", "DOB", "Location", "Color") 

df2 
# Num Last-Name First-Name Cat.  DOB Location Color 
# 1 11 Jackson  Adam L 1982-06-15  USA <NA> 
# 2 2  Pearl  Sam R 1986-11-04  UK <NA> 
# 3 5 Livingston  Steph LL 1983-12-12  USA <NA> 
# 4 7 Thornton  Mark LR 1982-03-26  USA <NA> 
# 5 10  Silver  John LL 1983-09-14  USA RED