我有一个数据框,其字符串如下:
string = ------ AJBHGC -----
我想将上面的字符串分成2列
string1 = ------#字母前的所有破折号为一个
string2 = AJBHGC -----#包括破折号在内的其他
structure(list(V1 = structure(c(1L, 3L, 2L), .Label = c("----ATCGDVC---",
"--CHBD----CHD--", "--CVGDVC"), class = "factor")), class = "data.frame", row.names = c(NA,
-3L))
当我尝试拆分时,将所有破折号和字母组合在一起。谁能帮忙
输出应如下所示:
structure(list(V1 = structure(c(1L, 3L, 2L), .Label = c("----ATCGDVC---",
"--CHBD----CHD--", "--CVGDVC"), class = "factor"), string1 = c("----",
"--", "--"), string2 = c("ATCGDVC---", "CVGDVC", "CHBD----CHD--"
)), row.names = c(NA, -3L), class = "data.frame")
谢谢!
答案 0 :(得分:5)
1)sub 用空字符串替换第一个非负号及其后的所有内容,以形成string1
。然后删除开头的负号以形成string2
。假设dd
是您数据框的名称,我们具有以下内容。不使用任何软件包。
transform(dd, string1 = sub("[^-].*", "", V1), string2 = sub("^-*", "", V1),
stringsAsFactors = FALSE)
给予:
V1 string1 string2
1 ----ATCGDVC--- ---- ATCGDVC---
2 --CVGDVC -- CVGDVC
3 --CHBD----CHD-- -- CHBD----CHD--
stringsAsFactors
参数是可选的。它确保结果是字符。如果省略它,则string1
和string2
将成为因素。
2)read.table 另一种可能性是在前减号后插入特殊字符(例如逗号),然后使用read.table
。同样,不使用任何软件包。
dd2 <- read.table(text = sub("^(-*)", "\\1,", dd$V1),
sep = ",", as.is = TRUE, col.names = c("string1", "string2"))
cbind(dd, dd2)
3)修剪如果您确实不需要string1
并且使用的是R 3.6或更高版本,则可以使用trimws
。同样,不使用任何软件包。
transform(dd, string2 = trimws(V1, "left", "-"), stringsAsFactors = FALSE)
给予:
V1 string2
1 ----ATCGDVC--- ATCGDVC---
2 --CVGDVC CVGDVC
3 --CHBD----CHD-- CHBD----CHD--
同样,stringsAsFactors
参数是可选的。
答案 1 :(得分:4)
1) 提取选项为extract
,用于捕获一个或多个+
字符(-
)从字符串(^
的开头开始,方法是将其捕获为方括号((...)
)内的组,然后将其他字符(.*
)捕获为第二组捕获组
library(dplyr)
library(tidyr)
df1 %>%
extract(V1, into = c("string1", "string2"), "^(-+)(.*)", remove = FALSE)
# V1 string1 string2
#1 ----ATCGDVC--- ---- ATCGDVC---
#2 --CVGDVC -- CVGDVC
#3 --CHBD----CHD-- -- CHBD----CHD--
2) 单独-或将separate
与正则表达式环顾四周
df1 %>%
separate(V1, into = c("string1", "string2"), "(?<=-)(?!-)",
extra = "merge", remove = FALSE)
# V1 string1 string2
#1 ----ATCGDVC--- ---- ATCGDVC---
#2 --CVGDVC -- CVGDVC
#3 --CHBD----CHD-- -- CHBD----CHD--
---没有下面的包装区/区域
3) regmatches / regexpr / trimws -base R
方法。在这里,我们使用regmatches/regexpr
提取前缀-
的字符,并使用trimws
删除前缀-
的字符。
df1[c("string1", "string2")] <- list(regmatches(df1$V1,
regexpr("^-+", df1$V1)), trimws(df1$V1, "left", "-"))
df1
# V1 string1 string2
#1 ----ATCGDVC--- ---- ATCGDVC---
#2 --CVGDVC -- CVGDVC
#3 --CHBD----CHD-- -- CHBD----CHD--
4)-捕获-或另一个base R
选项是strcapture
cbind(df1, strcapture("^(-+)(.*)", df1$V1,
list(string1 = character(0), string2 = character(0))))
# V1 string1 string2
#1 ----ATCGDVC--- ---- ATCGDVC---
#2 --CVGDVC -- CVGDVC
#3 --CHBD----CHD-- -- CHBD----CHD--
答案 2 :(得分:2)
可以说比应该做的要复杂得多,但还有另一种base
解决方案:
splits<-strsplit(gsub("(-(?=[A-Z]{4,}))([A-Z]+)","\\1 \\2",df$V1,
perl=TRUE),
"\\s(?<=)",perl=T)
df$string_1 <- sapply(splits,"[[",1)
df$string_2 <- sapply(splits, "[[", 2)
df
V1 string_1 string_2
1 ----ATCGDVC--- ---- ATCGDVC---
2 --CVGDVC -- CVGDVC
3 --CHBD----CHD-- -- CHBD----CHD--
编辑:
为避免不必要的重复sapply
,rbind
的写入可能会更有效:
data.frame(V1=df[,-c(2,3)],do.call(rbind,splits))#c(2,3) because I used the same df as above
V1 X1 X2
1 ----ATCGDVC--- ---- ATCGDVC---
2 --CVGDVC -- CVGDVC
3 --CHBD----CHD-- -- CHBD----CHD--
然后可以根据需要rename
对数据集进行操作。