2015-08-09 67 views
2

我想在一个数据帧d.df的一列中的数字和字符分隔:r分割的列分成多个列通过图案

col1 
ab 12 14 56 
xb 23 234 2342 2 
ad 23 45 

预期输出:

col1 col2 
ab  12 14 56 
xb  23 234 2342 2 
ad  23 45 

我承认这将是类似的东西,但我不知道分离器

t <- as.data.frame(str_match(d$col1,"^(.*)")) 

我试过很多方法ODS输出功率为:

col1  col2  
a   b 12 14 56 
x   b 23 234 2342 2 
a   d 23 45 

回答

2

这里的方法将会有很大的不同,这取决于这实际上是你的字符串的样子还是只是一个例子。如果他们总是两个字母和数字,你可以substring

> df <- data.frame(col1 = c("ab 12 14 56", "xb 23 234 2342 2", "ad 23 45")) 
> 
> df$col1.1 <- sapply(df$col1, substring, 0, 2) 
> 
> df$col1.2 <- sapply(df$col1, substring, 3) 
> 
> df 
       col1 col1.1   col1.2 
1  ab 12 14 56  ab  12 14 56 
2 xb 23 234 2342 2  xb 23 234 2342 2 
3   ad 23 45  ad   23 45 

如果长度和琴弦的持仓变化,正则表达式可能更适合。使用基础R的方法,你可以只提取数字或字母(保持空格):

> df <- data.frame(col1 = c("ab 12 14 56", "xb 23 234 2342 2", "ad 23 45")) 
> df$col1.1 <- sapply(regmatches(df$col1, gregexpr("[a-zA-Z]", df$col1)), paste, collapse = "") 
> df$col1.2 <- sapply(regmatches(df$col1, gregexpr("[0-9]\\s*", df$col1)), paste, collapse = "") 
> df 
       col1 col1.1  col1.2 
1  ab 12 14 56  ab  12 14 56 
2 xb 23 234 2342 2  xb 23 234 2342 2 
3   ad 23 45  ad   23 45 
+0

它的工作原理!谢谢! – Lucia

4

您可以使用separatetidyr

library(tidyr) 
d.df %>% separate(col1, c("col1", "col2"), sep="(?<=[a-z]{2})") 
# col1   col2 
# 1 ab  12 14 56 
# 2 xb 23 234 2342 2 
# 3 ad   23 45 

正则表达式,"(?<=[a-z]{2})",是一个向后看,意思是“在位置分割字符串在经过两次小写字符后跟一个空格”。 tidyr似乎对后视的长度有限制,所以{2}用于指定字母的数量。

3

这里是data.table一个选项。

library(data.table)#v1.9.5+ 
setnames(setDT(df1)[, tstrsplit(col1, 
     '(?<=[^0-9]) (?=[0-9])', perl=TRUE)], paste0('col', 1:2))[] 
# col1   col2 
#1: ab  12 14 56 
#2: xb 23 234 2342 2 
#3: ad   23 45 

我们将'data.frame'转换为'data.table'(setDT(df1))。在'data.table'的开发版本中使用tstrsplit,通过匹配字母后的空格和数字部分之前的空格,在'col1'中分隔空间。我们使用正则表达式((?<=[^0-9])和((?=[0-9]))进行匹配。