我正在与其他人的数据合作,其中列可能的值为" 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
列拆分为实际值long
或short
,以及仅包含带注释字符的新列。我可以使用以下内容到达中途,这正确地生成了一个仅包含注释字符的新列:
testdf %>% mutate(notes = gsub('long|short',"",vars)
但我无法弄清楚如何分割或分组var
,以便我得到一个只有short
或long
的列。
提前感谢您的帮助,SO社区! ^ _ ^
答案 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")