【问题标题】:Splitting character string in R based on characters基于字符在R中拆分字符串
【发布时间】:2017-01-28 17:13:34
【问题描述】:

我的数据集中有一列要拆分的字符串。

df = data.frame(col = c("BrBkRY","BBkRBr","YBRG","RBBk"))

这是我想用来有条件地分割的向量。

sep = c("Br","Bk","R","Y","B","G")

这就是它最终的样子。我是用手做的。

df2 = data.frame(col = c("BrBkRY","BBkRBr","YBRG","RBBk"), 
                 col1 = c("Br","B","Y","R"),
                 col2 = c("Bk","Bk","B","B"),
                 col3 = c("R","R","R","Bk"),
                 col4 = c("Y","Br","G",""))
df2 
     col col1 col2 col3 col4
1 BrBkRY   Br   Bk    R    Y
2 BBkRBr    B   Bk    R   Br
3   YBRG    Y    B    R    G
4   RBBk    R    B   Bk     

我正在考虑使用正则表达式,但通常,您需要像 .- 这样的拆分字符。但是对于基于字符的字符串,我不知道。此外,不想将 BkB 拆分为 B、k 和 B。但我确实想将其拆分为 Bk 和 B。有没有可以做到这一点的包?

【问题讨论】:

    标签: r string split


    【解决方案1】:

    您可以使用lookahead 和lookbehind 通过正则表达式进行拆分。该表达式表示在任何字符和大写字母之间的空格上进行拆分。 (?<=.) 指定前导“任何字符”,(?=[A-Z]) 指定后面的大写字母。 “任何角色”和国会大厦实际上并不是比赛的一部分,因此它们不会在分裂中“被吸走”。

    > lst <- strsplit(as.character(df$col), '(?<=.)(?=[A-Z])', perl=TRUE)
    > lst
    [[1]]
    [1] "Br" "Bk" "R"  "Y" 
    
    [[2]]
    [1] "B"  "Bk" "R"  "Br"
    
    [[3]]
    [1] "Y" "B" "R" "G"
    
    [[4]]
    [1] "R"  "B"  "Bk"
    

    然后可以构建列,例如完全按照 akrun 的回答:

    dfN <- cbind(df[1], do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))))
    colnames(dfN)[-1] <- paste0("col", colnames(dfN)[-1])
    

    【讨论】:

      【解决方案2】:

      我们可以使用str_extract_all提取list中的组件,然后rbind填充NA后的list元素使list元素的length相同,而cbind与原始数据集

      library(stringr)
      lst <- str_extract_all(df$col, paste(sep, collapse="|"))
      dfN <- cbind(df[1], do.call(rbind, lapply(lst, `length<-`, max(lengths(lst)))))
      colnames(dfN)[-1] <- paste0("col", colnames(dfN)[-1])
      dfN
      #     col col1 col2 col3 col4
      #1 BrBkRY   Br   Bk    R    Y
      #2 BBkRBr    B   Bk    R   Br
      #3   YBRG    Y    B    R    G
      #4   RBBk    R    B   Bk <NA>
      

      或者base R 选项与read.csvgsub 一起使用

      cbind(df[1], read.csv(text=sub("^,", "", gsub(paste0("(?=(",
          paste(sep, collapse="|"), "))"), ",", df$col, perl = TRUE)),  
           header=FALSE, col.names = paste0("col", 1:4), fill = TRUE))
      #     col col1 col2 col3 col4
      #1 BrBkRY   Br   Bk    R    Y
      #2 BBkRBr    B   Bk    R   Br
      #3   YBRG    Y    B    R    G
      #4   RBBk    R    B   Bk     
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-28
        • 2019-05-08
        相关资源
        最近更新 更多