【问题标题】:R: How to separate values only after the second spaceR:如何仅在第二个空格之后分隔值
【发布时间】:2017-06-12 11:52:56
【问题描述】:

我有一列名称不同:

X <- c("Ashley, Tremond WILLIAMS, Carla", "Claire, Daron", "Luw, Douglas CANSLER, Stephan")

在第二个空格之后,它以第二个人的名字开头。例如,Ashley, Tremond 是一个人,WILLIAMS, Carla 是另一个人。

我试过了:

strsplit(X, "\\,\\s|\\,|\\s")

但它除以所有空格,所以我得到:

strsplit(X, "\\,\\s|\\,|\\s")
[[1]]
[1] "Ashley"   "Tremond"  "WILLIAMS" "Carla"   

[[2]]
[1] "Claire" "Daron" 

[[3]]
[1] "Luw"     "Douglas" "CANSLER" "Stephan"

我怎样才能只在第一个空格之后分开,所以我得到了?:

[1] "Ashley, Tremond"  "WILLIAMS, Carla"   

[[2]]
[1] "Claire, Daron" 

[[3]]
[1] "Luw, Douglas" "CANSLER, Stephan"

提前感谢您的所有帮助

【问题讨论】:

  • strsplit(X, "[^,] ") 给出所需的输出。它在空格前面没有逗号的地方拆分字符串。
  • 您需要将其取消列出以维护向量:unlist(strsplit(X, split = "[A-z] [A-z]"))
  • @RyanMorton ,如果您跳过 unlist 调用,它会保留原始输入中名称的分组级别,并匹配预期输出
  • 在我最初的回复之后,预期的结果被编辑到帖子中,但是是的。 strsplit() 返回一个列表。
  • @ykt 和 Ryan 非常感谢您的帮助,它有效

标签: r separator strsplit


【解决方案1】:

当然@ytk 的评论有效,但如果你想避免使用正则表达式, 你可以偷偷摸摸地做

df2 <- df %>%
  separate(col = X, into=c("person1a","person1b","person2a","person2b"),sep= " ") %>%
  unite(col = "person1", person1a, person1b, sep=" ") %>%
  unite(col = "person2", person2a, person2b, sep=" ") 

返回:

> df2
          person1          person2
1 Ashley, Tremond  WILLIAMS, Carla
2   Claire, Daron            NA NA
3    Luw, Douglas CANSLER, Stephan

附言我使用df &lt;- data.frame(X = c("Ashley, Tremond WILLIAMS, Carla", "Claire, Daron", "Luw, Douglas CANSLER, Stephan")) 将输入变成数据框。

【讨论】:

  • 谢谢,但我写了完全相同的代码,但它对我不起作用,我也不太明白,%>% 是什么意思?
  • @NataliaP 这是piping 语法的一种方式,请查看magrittr 包。
【解决方案2】:

您可以将stringr::str_match^(\S+(?:\s+\S+)?)?(?:\s+(.+))? 正则表达式一起使用(参见regex demo online):

library(stringr)
str_match(x, "(?s)^(\\S+(?:\\s+\\S+)?)?(?:\\s+(.+))?")[,-1]
# => [1] "string I"                      "would like to split somewhere"

另外,你可以使用utils::strcapture:

result <- utils::strcapture("^(\\S+(?:\\s+\\S+)?)?(?:\\s+(.+))?", x, list(left=character(), right=character()))
# > result
#        left                         right
#  1 string I would like to split somewhere
result$left
# => [1] "string I"
result$right
# => [1] "would like to split somewhere"

^(\S+(?:\s+\S+)?)?(?:\s+(.+))? 正则表达式匹配

  • ^ - 字符串开头
  • (\S+(?:\s+\S+)?)? - 可选组 1:
    • \S+ - 一个或多个非空白字符
    • (?:\s+\S+)? - 可选地出现一个或多个空格,然后出现一个或多个非空格
  • (?:\s+(.+))? - 可选出现
    • \s+ - 一个或多个空格
    • (.+) - 第 2 组:除换行符之外的一个或多个字符尽可能多。

请注意,在这里使用stringr::str_split 是不安全的,因为使用它的唯一方法是使用受限宽度的后视:

str_split(x, "(?<=^\\S{1,1000}\\s{1,1000}\\S{1,1000})\\s+")
# => [[1]]
#    [1] "string I"                      "would like to split somewhere"

由于在限制宽度的后视中不能使用+* 量词,您所能做的就是使用带有声明的最小和最大参数的限制量词{1,1000}。在这里,1000 个字符是您需要根据数据调整的限制。

【讨论】:

    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 2022-07-07
    • 2021-08-20
    • 1970-01-01
    • 2021-08-13
    • 2014-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多