【问题标题】:Split a column of a table to multiple columns given the input of separators [duplicate]给定分隔符的输入,将表的一列拆分为多列[重复]
【发布时间】:2017-08-23 09:24:37
【问题描述】:

也许我想做的事情是不可能的,所以我提出这个问题是为了知道是否有办法。 在 stackoverflow 中阅读此question 后,我看到有一种方法可以将一列拆分为不同的列,但这不是我想要的,我有一个闪亮的应用程序,我可以有如下值的表:

Phones                             price
Nokia 1234D - J298 6732 - LM 2       103$
Samsung 3342L - J2YY 4372 - YU 3     130$
Samsung 3042X - IKAA 3221 - GN 4    102$

所以用户来说我想按我的意愿在列 Phones 中划分这些值,所以我想到的想法是让用户写类似 (" ", " - ", " ", " - ") 因为我的意思是在给定上述分隔符的情况下将 nokia, 1234D, J298, 6732, LM 2 分成 5 列。

示例代码如下:

library(stringr)
c=c(" "," - "," "," - ")
mytable <-data.table(Phones=c("Nokia 1234D - J298 6732 - LM 2",      
                                      "Samsung 3342L - J2YY 4372 - YU 3",
                                      "Samsung 3042X - IKAA 3221 - GN 4"),price= c("103$", "130$", "102$") )
 aux = str_split_fixed(mytable$Phones, c, 5)
  mytable<-data.table( aux, mytable$price)

但我得到以下结果,这不是我想要的结果,它按需要分开,重复第一行。:

              V1        V2   V3   V4          V5   V2
1:         Nokia     1234D    - J298 6732 - LM 2 103$
2: Samsung 3342L J2YY 4372 YU 3                  130$
3:       Samsung     3042X    - IKAA 3221 - GN 4 102$
4:   Nokia 1234D J298 6732 LM 2                  103$     

如果您有更好的解决方案,那将非常有帮助。

【问题讨论】:

    标签: r regex


    【解决方案1】:

    我们可以将separate 'Phones' 列分成 5 列,使用 extra= "merge" 以保留最后一列的字符串 "LM 2", "YU 3"

    library(tidyr)
    library(dplyr)
    mytable %>% 
      separate(Phones, into = paste0("V", 1:5), remove = FALSE, extra = "merge")
    #                             Phones      V1    V2   V3   V4   V5 price
    #1:   Nokia 1234D - J298 6732 - LM 2   Nokia 1234D J298 6732 LM 2  103$
    #2: Samsung 3342L - J2YY 4372 - YU 3 Samsung 3342L J2YY 4372 YU 3  130$
    #3: Samsung 3042X - IKAA 3221 - GN 4 Samsung 3042X IKAA 3221 GN 4  102$
    

    如果我们需要自定义拆分,请使用extract

    mytable %>%
       extract(Phones, into = paste0("V", 1:4), remove = FALSE, 
         "^(\\w+\\s+\\w+)\\s*-\\s*(\\w+)\\s+(\\w+)\\s*-\\s*(\\w+\\s+\\w+)")
    #                             Phones            V1   V2   V3   V4 price
    #1:   Nokia 1234D - J298 6732 - LM 2   Nokia 1234D J298 6732 LM 2  103$
    #2: Samsung 3342L - J2YY 4372 - YU 3 Samsung 3342L J2YY 4372 YU 3  130$
    #3: Samsung 3042X - IKAA 3221 - GN 4 Samsung 3042X IKAA 3221 GN 4  102$
    

    ^ 表示字符串的开头,后跟单词 (\\w+),后跟一个或多个空格 (\\s+) 和下一个单词 (\\w+),我们将其捕获为一个组 (@987654331 @) 同样,字符是根据单词、空格字符匹配的

    注意:第一种方法给出了帖子中描述的预期输出,第二种方法来自 cmets 中请求的输出


    如果我们需要通过“c”中的自定义拆分来拆分

    library(stringr)
    c <- c(" "," - "," "," - ") #it is better to avoid function names for object names
    fsplit <- function(str1, splt) {
           lst <- str_split(str1, splt, n = 2)
           v1 <- sapply(lst, `[`, 1)
           v2 <- sapply(lst, `[`, 2)
           list(v1, v2)
        }  
    
    mytable[, V5 := Phones]
    nm1 <- paste0("V", seq_along(c))
    for(i in seq_along(c)){
      tmp <- fsplit(mytable$V5, c[i])
      mytable[, (nm1[i]) := tmp[[1]]]
      mytable[, V5 := tmp[[2]]][]
    }
    setcolorder(mytable,  c("Phones", nm1, "V5", "price"))
    mytable
    #                             Phones      V1    V2   V3   V4   V5 price
    #1:   Nokia 1234D - J298 6732 - LM 2   Nokia 1234D J298 6732 LM 2  103$
    #2: Samsung 3342L - J2YY 4372 - YU 3 Samsung 3342L J2YY 4372 YU 3  130$
    #3: Samsung 3042X - IKAA 3221 - GN 4 Samsung 3042X IKAA 3221 GN 4  102$
    

    【讨论】:

    • 这行得通,但如果用户想将Nokia 1234D 保持在一起怎么办?
    • @David Arenburg 感谢您的评论正是我想说的!
    • 谢谢@akrun,但你能解释一下这段代码^(\\w+\\s+\\w+)\\s*-\\s*(\\w+)\\s+(\\w+)\\s*-\\s*(\\w+) 到底是做什么的吗?在第V4 列它应该是LM 2 ...它删除了数字。
    • @ProgrammerMan 我更新了自定义拆分。抱歉,我想采用简单的方法而不是自定义拆分
    • 谢谢!!适用于不同的给定输入! @akrun
    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 2018-03-17
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    相关资源
    最近更新 更多