受到哈德利在这个答案中的漂亮gather
方法的启发,我尝试使用tidyrgather()
并spread()
结合正则表达式regex
,但我似乎在regex
.
我确实研究了几个regex
问题;这个,这个,还有regex101.com。我试图regex
通过使用来规避starts_with()
,ends_with()
并matches()
受到这个问题的启发,但没有运气。
我在这里问是希望有人能指出我哪里弄错了,我可以解决它,最好使用来自tidyselect的选择助手。
我需要选择 2 个regex
组,一个到最后一个.
,一个由最后一个组成.
,我在下面做了两个示例,一个在我的代码工作的地方,一个在我被卡住的地方。
首先是有效的例子,
# install.packages(c("tidyverse"), dependencies = TRUE)
require(tidyverse)
第一个数据集,工作,看起来像这样,
myData1 <- tibble(
id = 1:10,
Wage.1997.1 = c(NA, 32:38, NA, NA),
Wage.1997.2 = c(NA, 12:18, NA, NA),
Wage.1998.1 = c(NA, 42:48, NA, NA),
Wage.1998.2 = c(NA, 2:8, NA, NA),
Wage.1998.3 = c(NA, 42:48, NA, NA),
Job.Type.1997.1 = NA,
Job.Type.1997.2 = c(NA, rep(c('A', 'B'), 4), NA),
Job.Type.1998.1 = c(NA, rep(c('A', 'B'), 4), NA),
Job.Type.1998.2 = c(NA, rep(c('A', 'B'), 4), NA)
)
我就是gather()
这样,
myData1 %>% gather(key, value, -id) %>%
extract(col = key, into = c("variable", "id.job"), regex = "(.*?\\..*?)\\.(.)$") %>%
spread(variable, value)
#> # A tibble: 30 x 6
#> id id.job Job.Type.1997 Job.Type.1998 Wage.1997 Wage.1998
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 1 1 <NA> <NA> <NA> <NA>
#> 2 1 2 <NA> <NA> <NA> <NA>
#> 3 1 3 <NA> <NA> <NA> <NA>
#> 4 2 1 <NA> A 32 42
#> 5 2 2 A A 12 2
#> 6 2 3 <NA> <NA> <NA> 42
#> 7 3 1 <NA> B 33 43
#> 8 3 2 B B 13 3
#> 9 3 3 <NA> <NA> <NA> 43
#> 10 4 1 <NA> A 34 44
#> # ... with 20 more rows
它有效,我怀疑我用 . 过度使用它regex
,但它有效。但是,我的真实数据最后可以有一个或两个摘要,即
第二个数据,我卡住的地方,
myData2 <- tibble(
id = 1:10,
Wage.1997.1 = c(NA, 32:38, NA, NA),
Wage.1997.12 = c(NA, 12:18, NA, NA),
Wage.1998.1 = c(NA, 42:48, NA, NA),
Wage.1998.12 = c(NA, 2:8, NA, NA),
Wage.1998.13 = c(NA, 42:48, NA, NA),
Job.Type.1997.1 = NA,
Job.Type.1997.12 = c(NA, rep(c('A', 'B'), 4), NA),
Job.Type.1998.1 = c(NA, rep(c('A', 'B'), 4), NA),
Job.Type.1998.12 = c(NA, rep(c('A', 'B'), 4), NA)
)
现在,这是我(0[0-1]|1[0-9])$
用于第二组的地方,我也尝试过类似的东西\d{1}|\d{2}
,但这也不起作用。
myData2 %>% gather(key, value, -id) %>%
extract(col = key, into = c("variable", "id.job"),
regex = "(.*?\\..*?)\\.(0[0-1]|1[0-9])$") %>%
spread(variable, value)
预期的输出将是这样的,
#> # A tibble: 30 x 6
#> id id.job Job.Type.1997 Job.Type.1998 Wage.1997 Wage.1998
#> <int> <chr> <chr> <chr> <chr> <chr>
#> 1 1 1 <NA> <NA> <NA> <NA>
#> 2 1 12 <NA> <NA> <NA> <NA>
#> 3 1 13 <NA> <NA> <NA> <NA>
#> 4 2 1 <NA> A 32 42
#> 5 2 12 A A 12 2
#> 6 2 13 <NA> <NA> <NA> 42
#> 7 3 1 <NA> B 33 43
#> 8 3 12 B B 13 3
#> 9 3 13 <NA> <NA> <NA> 43
#> 10 4 1 <NA> A 34 44
#> # ... with 20 more rows
一个简单的解决方案 à la t this question using select helpers like starts_with()
, ends_with()
, matches()
, 等将不胜感激。