在第一个空格上拆分字符串

时间:2011-11-28 17:42:06

标签: regex r

我想将字符串(人名)的矢量分成两列(矢量)。问题是有些人有一个“两个字”的姓氏。我想将名字和姓氏分成两列。我可以使用下面的代码切出并使用名字,但姓氏使我无效。 (看看下面的样本集中的obs 29,以了解福特有一个必须保持在一起的Pantera L的“姓氏”)

到目前为止我试图做的事情;

x<-rownames(mtcars)
unlist(strsplit(x, " .*"))

我希望它看起来像:

            MANUF       MAKE
27          Porsche     914-2
28          Lotus       Europa
29          Ford        Pantera L
30          Ferrari     Dino
31          Maserati    Bora
32          Volvo       142E

6 个答案:

答案 0 :(得分:26)

正则表达式rexp匹配字符串开头的单词,可选空格,然后是字符串的其余部分。括号是子表达式,作为反向引用\\1\\2

rexp <- "^(\\w+)\\s?(.*)$"
y <- data.frame(MANUF=sub(rexp,"\\1",x), MAKE=sub(rexp,"\\2",x))
tail(y)
#       MANUF      MAKE
# 27  Porsche     914-2
# 28    Lotus    Europa
# 29     Ford Pantera L
# 30  Ferrari      Dino
# 31 Maserati      Bora
# 32    Volvo      142E

答案 1 :(得分:17)

对我而言,Hadley在colsplit包中的reshape2函数对于此目的来说是最直观的。约书亚的方式更为通用(即可以在任何可以使用正则表达式的地方使用)和灵活的(如果你想改变规范);但colsplit函数非常适合这个特定的设置:

library(reshape2)
y <- colsplit(x," ",c("MANUF","MAKE"))
tail(y)
#      MANUF      MAKE
#27  Porsche     914-2
#28    Lotus    Europa
#29     Ford Pantera L
#30  Ferrari      Dino
#31 Maserati      Bora
#32    Volvo      142E

答案 2 :(得分:11)

以下是两种方法:

1)strsplit 。此方法仅使用R核心中的函数,并且不使用复杂的正则表达式。将第一个空格替换为分号(使用sub gsub),strsplit替换分号,然后将rbind替换为2列矩阵:

mat <- do.call("rbind", strsplit(sub(" ", ";", x), ";"))
colnames(mat) <- c("MANUF", "MAKE")

2)gsubfn包中的strapply 这是gsubfn包中使用strapply的单行内容。正则表达式的两个带括号的部分分别捕获所需的第一列和第二列,并且函数(在公式表示法中指定 - 与指定function(x, y) c(MANUF = x, MAKE = y)相同)抓取它们并添加名称。 simplify=rbind参数用于将其转换为矩阵,如前面的解决方案。

library(gsubfn)
mat <- strapply(x, "(\\S+)\\s+(.*)", ~ c(MANUF = x, MAKE = y), simplify = rbind)

注意:在任何一种情况下,都会返回"character"矩阵mat。如果需要"character"列的数据框,请添加以下内容:

DF <- as.data.frame(mat, stringsAsFactors = FALSE)

如果需要stringsAsFactors列,则省略"factor"参数。

答案 3 :(得分:7)

另一种方法:

来自str_split

stringr将处理拆分,但会以不同的形式(列表,如strsplit)返回。然而,操纵到正确的形式是很简单的。

library(stringr)
split_x <- str_split(x, " ", 2)
(y <- data.frame(
  MANUF = sapply(split_x, head, n = 1),
  MAKE  = sapply(split_x, tail, n = 1)
))

或者,正如哈德利在评论中提到的str_split_fixed

y <- as.data.frame(str_split_fixed(x, " ", 2))
colnames(y) <- c("MANUF", "MAKE")
y

答案 4 :(得分:0)

如果你可以进行模式和组匹配,我会尝试这样的事情(未经测试):

\s+(.*)\s+(.*)

答案 5 :(得分:0)

我认为搜索[^\s]+会有效。未经测试。