提问人:Sam 提问时间:5/15/2020 更新时间:5/16/2020 访问量:130
当行间的片段数不同时,将字符串拆分为三列
Split character string into three columns when number of pieces differs between rows
问:
我有一个类似于以下 reprex 的数据帧:
test <- data.frame(
age = c("6 hours", "2 days, 4 hours", "1 months3 days, 7 hours")
)
不幸的是,正如您在第 3 行中看到的那样,字符串的三部分并非都用逗号分隔。
我的预期输出如下:
age agem aged ageh
1 6 hours NA NA 6
2 2 days, 4 hours NA 2 4
3 1 months3 days, 7 hours 1 3 7
我试过这样使用dplyr::separate
new_test <- test %>%
separate(age, c("agem", "ageh", "aged"), sep = "[^[\\d]]+", convert = TRUE,
remove = FALSE, fill = "left")
这对于只有“小时”的条目非常有效,但如果有“天和小时”或“月、天和小时”,则输出的顺序是错误的。
任何帮助将不胜感激。
答:
3赞
Rui Barradas
5/15/2020
#1
首先,在字母字符和数字之间没有分隔符的地方添加分隔符。然后进入列。tidyr::separate
library(tidyverse)
test %>%
mutate(age = gsub("([[:alpha:]])([[:digit:]])", "\\1, \\2", age)) %>%
separate(age, into = c('agem', 'aged', 'ageh'),
sep = ', ',
convert = TRUE,
remove = FALSE, fill = "left") %>%
mutate_at(vars(matches('age[[:alpha:]]')), function(x) as.numeric(gsub('[^[:digit:]]', '', x)))
# age agem aged ageh
#1 6 hours NA NA 6
#2 2 days, 4 hours NA 2 4
#3 1 months, 3 days, 7 hours 1 3 7
评论
0赞
Shan R
5/15/2020
很棒的解决方案。@Sam,如果您需要删除新列的文本部分,一种方法是使用 Library Readr 中的parse_number。
0赞
Chris Ruehlemann
5/16/2020
文本部分不包括在预期成果中
3赞
Chris Ruehlemann
5/16/2020
#2
您可以使用包和积极的展望:str_extract
stringr
(?= ...)
test$agem <- str_extract(test$age, "\\d+(?=\\smonth)")
test$aged <- str_extract(test$age, "\\d+(?=\\sday)")
test$ageh <- str_extract(test$age, "\\d+(?=\\shour)")
结果:
test
age agem aged ageh
1 6 hours <NA> <NA> 6
2 2 days, 4 hours <NA> 2 4
3 1 months3 days, 7 hours 1 3 7
评论
0赞
Sam
9/17/2020
一个非常简单而优雅的解决方案,效果很好,谢谢。对于延迟,我深表歉意,但我现在已将其标记为公认的答案,因为尽管两个发布的解决方案都有效,但这是我使用的解决方案,也是最简洁的解决方案。
评论