2016-05-17 70 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 
相关问题