问题 在第一个遇到的数字上使用单独的(tidyr)通过dplyr分离色谱柱


我试图将一个相当混乱的列分成两列包含  和 描述。我的数据类似于下面的摘录:

set.seed(1)
dta <- data.frame(indicator=c("someindicator2001", "someindicator2011",
                              "some text 20022008", "another indicator 2003"),
                  values = runif(n = 4))

期望的结果

期望的结果应该如下:

          indicator   period    values
1     someindicator     2001 0.2655087
2     someindicator     2011 0.3721239
3         some text 20022008 0.5728534
4 another indicator     2003 0.9082078

特点

  1. 指标描述在一列中
  2. 数值(从第一个数字开始计算)  第一个数字在第二列)

require(dplyr); require(tidyr); require(magrittr)
dta %<>%
  separate(col = indicator, into = c("indicator", "period"),
           sep = "^[^\\d]*(2+)", remove = TRUE)

当然这不起作用:

> head(dta, 2)
  indicator period    values
1              001 0.2655087
2              011 0.3721239

其他尝试

  • 我也尝试过默认的分离方法 sep = "[^[:alnum:]]" 但它将列拆分为太多列,因为它似乎匹配所有可用的数字。
  • sep = "2*" 也不起作用,因为有时太多2s (例: 20032006)

我想要做的是归结为:

  • 识别字符串中的第一个数字
  • 在该章程上分开。 事实上,我也很乐意保留这个特殊的角色。

5573
2018-01-17 19:17


起源



答案:


我想这可能会这样做。

library(tidyr)
separate(dta, indicator, c("indicator", "period"), "(?<=[a-z]) ?(?=[0-9])")
#           indicator   period    values
# 1     someindicator     2001 0.2655087
# 2     someindicator     2011 0.3721239
# 3         some text 20022008 0.5728534
# 4 another indicator     2003 0.9082078

以下是由您带来的正则表达式的解释 regex101

  • (?<=[a-z]) 是一个积极的外观 - 它断言 [a-z] (匹配a和z之间范围内的单个字符(区分大小写))可以匹配
  • ? 在字面上匹配前面的空格字符,在零和一次之间,尽可能多次,根据需要返回
  • (?=[0-9]) 是一个积极的前瞻 - 它断言 [0-9] (匹配0到9范围内的单个字符)可以匹配

14
2018-01-17 19:42



谢谢,这太棒了,它 似乎是 正确匹配结果,非常感谢您的解释。我想到解决这个问题可能会涉及到 回顾后/向前 但我发现它们不易使用。 - Konrad


答案:


我想这可能会这样做。

library(tidyr)
separate(dta, indicator, c("indicator", "period"), "(?<=[a-z]) ?(?=[0-9])")
#           indicator   period    values
# 1     someindicator     2001 0.2655087
# 2     someindicator     2011 0.3721239
# 3         some text 20022008 0.5728534
# 4 another indicator     2003 0.9082078

以下是由您带来的正则表达式的解释 regex101

  • (?<=[a-z]) 是一个积极的外观 - 它断言 [a-z] (匹配a和z之间范围内的单个字符(区分大小写))可以匹配
  • ? 在字面上匹配前面的空格字符,在零和一次之间,尽可能多次,根据需要返回
  • (?=[0-9]) 是一个积极的前瞻 - 它断言 [0-9] (匹配0到9范围内的单个字符)可以匹配

14
2018-01-17 19:42



谢谢,这太棒了,它 似乎是 正确匹配结果,非常感谢您的解释。我想到解决这个问题可能会涉及到 回顾后/向前 但我发现它们不易使用。 - Konrad