R分割由不同数量的空格分隔的字符列

时间:2016-07-30 00:38:26

标签: r split

我有一个数据框,其中的列由不同数量的空格分隔的单词组成,例如:

head(lst)
'fff fffd ddd'
'sss dd'
'de dd'
'dds sssd eew rrr'
'dsds eed'

我想要的是2列: 第一列是第一个空格之前的部分 第二列是最后一个空格后的部分 意思是它应该喜欢这个

V1       v2
'fff'   'ddd'
'sss'   'dd'
'de'    'dd'
'dds'   'rrr
'dsds'  'eed'

我能够获得的第一列,但第二列是一个问题 这是我使用的代码。

  lst <- strsplit(athletes.df$V1, "\\s+")
  v1 <- sapply(lst ,`[`, 1)
  v2 <- sapply(lst, `[`, 2)

我得到的第v2列是第二个词。我知道这是因为我把2放在了sapply中我怎么告诉它只能拿到最后一个空格后的内容?

3 个答案:

答案 0 :(得分:3)

您可以使用tail获取每个向量的最后一个条目:

lst <- strsplit(athletes.df$V1, "\\s+")
v1 <- sapply(lst, head, 1) # example with head to grab first vector element
v2 <- sapply(lst, tail, 1) # example with tail to grab last vector element

或许是vapply版本,因为您知道您的返回类型应该是字符向量:

v2 <- vapply(lst, tail, 1, FUN.VALUE = character(1))

另一种方法是将您的strsplit拆分条件修改为这样的区域,在这个区域中,您可以选择一个或多次跟随任何字符的空格,直到找到最终空格。

strsplit(df$V1, "\\s(?:.+\\s)?")
#[[1]]
#[1] "fff" "ddd"
#
#[[2]]
#[1] "sss" "dd" 
#
#[[3]]
#[1] "de" "dd"
#
#[[4]]
#[1] "dds" "rrr"
#
#[[5]]
#[1] "dsds" "eed"

正如Sumedh所指出的,这个正则表达式与tidyr separate很好地配合使用:

tidyr::separate(df, V1, c("V1", "V2"), "\\s(?:.+\\s)?")
#    V1  V2
#1  fff ddd
#2  sss  dd
#3   de  dd
#4  dds rrr
#5 dsds eed

两种基于stringi的方法:

library(stringi)
v1 <- stri_extract_last_regex(df$V1, "\\S+")
v2 <- stri_extract_first_regex(df$V1, "\\S+")

或者

stri_extract_all_regex(df$V1, "^\\S+|\\S+$", simplify = TRUE)
# this variant explicitly checks for the spaces with lookarounds:
stri_extract_all_regex(df$V1, "^\\S+(?=\\s)|(?<=\\s)\\S+$", simplify = TRUE)

答案 1 :(得分:1)

也许这个?

lst <- strsplit(athletes.df$V1, "\\s+")
v1 <- sapply(lst ,`[`, 1)
v2 <- sapply(lst, function(x) x[length(x)])

或者

data.frame(t(sapply(strsplit(athletes.df$V1, "\\s+"), 
                    function(x) c(x[1], x[length(x)]))))

答案 2 :(得分:0)

在不使用任何软件包的情况下,使用read.table创建分隔符后,可以使用sub完成此操作。

read.table(text=sub("^(\\S+)\\s+.*\\s+(\\S+)$", "\\1 \\2", df1$V1), 
                     header=FALSE, stringsAsFactors= FALSE)
#     V1  V2
#1  fff ddd
#2  sss  dd
#3   de  dd
#4  dds rrr
#5 dsds eed

另一个方便的选项是来自word

stringr
library(stringr)
transform(df1, V1 = word(V1, 1), V2 = word(V1, -1))
#   V1  V2
#1  fff ddd
#2  sss  dd
#3   de  dd
#4  dds rrr
#5 dsds eed

数据

df1 <- structure(list(V1 = c("fff fffd ddd", "sss dd", "de dd",
"dds sssd eew rrr", 
"dsds eed")), .Names = "V1", class = "data.frame", row.names = c(NA, 
-5L))