将字符串拆分为两列

时间:2017-12-04 17:22:45

标签: r regex string

我正在与其他人的数据合作,其中列可能的值为" short"和#34;长"。不幸的是,数据创建者还在这些单词之后添加了字母和问号来注释某些内容,我想将其拆分为单独的列。这里有一些假数据可供使用:

vars <- c('long','short','longG','short?','short?F','long?G')
species <- c('sp1','sp2','sp3','sp4','sp5','sp6')
testdf <- cbind(vars, species)

我想将vars列拆分为实际值longshort,以及仅包含带注释字符的新列。我可以使用以下内容到达中途,这正确地生成了一个仅包含注释字符的新列:

testdf %>% mutate(notes = gsub('long|short',"",vars)

但我无法弄清楚如何分割或分组var,以便我得到一个只有shortlong的列。

提前感谢您的帮助,SO社区! ^ _ ^

2 个答案:

答案 0 :(得分:2)

很难在base R中提取字符串片段而是使用stringr代替:

library(stringr)
str_extract(vars, 'long|short')
# [1] "long"  "short" "long"  "short" "short" "long" 

(您可以在mutate或其他地方使用它。)

所以你的完整例子(我将参数化模式以获得良好的衡量标准)

pattern = "long|short"
mutate(testdf,
   notes = gsub(pattern, "", vars),
   notes2 = str_replace(vars, pattern, ""), # stringr alternative for consistent syntax
   ls = str_extract(vars, pattern))

答案 1 :(得分:2)

问题中的

testdf是矩阵,因此将其转换为具有以下两种选择之一的数据框:

1)sub 一个mutate,其中sub次调用具有相同的模式pat但具有不同的替换。

pat <- "(long|short)(.*)"
testdf %>% 
       as.data.frame %>%
       mutate(notes = sub(pat, "\\2", vars), 
              vars = sub(pat, "\\1", vars))

,并提供:

   vars  species notes
1  long      sp1      
2 short      sp2      
3  long      sp3     G
4 short      sp4     ?
5 short      sp5    ?F
6  long      sp6    ?G

2)分开在长或短之后插入分号(或其他字符),然后使用来自tidyr的separate。请注意,即使注释包含分号也是如此,因为它只在第一个分号处分割。

library(tidyr)

testdf %>% 
       as.data.frame %>%
       mutate(vars = sub("(long|short)", "\\1;", vars)) %>%
       separate(vars, c("vars", "notes"), sep = ";", extra = "merge")

,并提供:

   vars notes  species
1  long            sp1
2 short            sp2
3  long     G      sp3
4 short     ?      sp4
5 short    ?F      sp5
6  long    ?G      sp6

注意,如果总有?分开笔记然后它可以简化为:

testdf %>% 
       as.data.frame %>%
       separate(vars, c("vars", "notes"), sep = "\\?", extra = "merge")