2016-05-17 69 views
1

我已經從一個源數據刮掉網上創建n行的有關個人信息的數據幀(df1)。它以單個字符串形式出現,我將這些單詞拆分爲適當的列。更換價值與移位數據幀,如果某些條件已滿足

90%的信息被正確格式化爲數據框中正確的列數(6) - 但是,偶爾有一行數據帶有一個額外的單詞,位於從字符串開始的第4個字。這些行現在有7列,並且與數據框中的其他所有內容相抵消。

下面是一個例子:

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") 

你可以看到項目#10有一個額外的輸入增加,顏色"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

我們可以使用gsub刪除多餘子

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

這裏有一個簡單的方法:

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

第一GSUB調換顏色字符串的結尾。第二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 
相關問題