【问题标题】:Conditional string split in data.table in RR中data.table中的条件字符串拆分
【发布时间】:2017-10-01 07:44:31
【问题描述】:

基于这个问题:Split text string in a data.table columns,我想知道是否有一种有效的方法可以根据行的内容有条件地拆分文本字符串。

假设我有下表:

Comments                  Eaten
001 Testing my computer   No
0026 Testing my fridge    No
Testing my car            Yes

我想要这个:

ID   Comments             Eaten
001  Testing my computer  No
0026 Testing my fridge    No
NA   Testing my car       Yes

NA 为空。

这可能在 data.table 中吗?

评论应该有一个 ID,但由于这是可选的,我只想在当且仅当评论以数字开头时提取 ID。

【问题讨论】:

  • 所以你知道应该有一个 ID 和 cmets 或者这应该被自动检测到?
  • ID 是可选的,但如果评论以数字开头,那么它应该自动成为 ID。

标签: r regex data.table


【解决方案1】:

这可以使用tidyrextract 函数来完成,该函数允许您指定正则表达式模式:

tidyr::extract(dt, Comments, c("ID", "Comments"), regex = "^(\\d+)?\\s?(.*)$")
#     ID            Comments Eaten
#1:  001 Testing my computer    No
#2: 0026   Testing my fridge    No
#3:   NA      Testing my car   Yes

如果您希望将提取的列转换为更合理的类型,可以添加参数convert = TRUE


仅使用基本 R 和 data.table 的另一个选项是

dt[grepl("^\\d+", Comments),                     # check if start with ID (subset)
   `:=`(ID = sub("^(\\d+).*", "\\1",Comments),   # extract ID from comments
        Comments = sub("^(\\d+)", "",Comments))  # delete ID from Comments
]

虽然在这种情况下,tidyr 语法对我来说似乎更容易一些。还有一种方法可以使用 data.table 的 tstrsplit 函数和一个花哨的环视正则表达式。

【讨论】:

  • transpose(regmatches(x, regexec("^(\\d+)? ?(.*)", x))) 或类似的,我猜。未测试,因为 OP 的数据不可复制粘贴...
  • R 3.4.0 还有一个适合这里的strcapture 函数——strcapture("^(\\d+)?\\s?(.*)$", dt$Comments, data.frame(ID = "", Comment = ""))
  • @alexis_laz 看起来很有趣,但对于那些空字符串也有点奇怪。我还没有升级到 3.4.0
猜你喜欢
  • 2021-04-01
  • 1970-01-01
  • 2015-11-03
  • 2014-09-16
  • 1970-01-01
  • 2014-07-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-11
相关资源
最近更新 更多