将字符串中的“-”分割为列

时间:2019-07-23 18:53:48

标签: r

我有一个数据框,其字符串如下:

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")

谢谢!

3 个答案:

答案 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参数是可选的。它确保结果是字符。如果省略它,则string1string2将成为因素。

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--

编辑: 为避免不必要的重复sapplyrbind的写入可能会更有效:

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对数据集进行操作。