【问题标题】:Splitting string into multiple columns将字符串拆分为多列
【发布时间】:2019-05-22 21:28:47
【问题描述】:

我的数据框中有以下字符串结构作为列值:

Y:10,W:3,cp:0.05

每行的数值不同,但结构保持不变。我想将此字符串拆分为 3 列,每列仅包含数字。因此,Y 将有一列具有相应的数值,W 为另一列,cp 为最后一列。

我曾尝试通过以下方式使用 str_split:

str_split(string,pattern = " ,",simplify = TRUE )

这显然给了我:

     [,1]     [,2]   [,3]       
[1,] "Y: 40 " "W: 2" " cp: 0.05"

现在,我只想保留每列中的数字。还在学习这些东西,所以不知道如何继续!非常感谢任何帮助!

【问题讨论】:

  • stringr::str_replace(stringr::str_split(string, ",", simplify=TRUE), "^.*:\\s?", "")

标签: r string


【解决方案1】:

肯定有更好的方法,但这应该可以完成工作:

现在针对具有多个元素的字符串向量进行了更新,并将其带入具有三个命名列的矩阵中。应该适用于任何长度的向量。

library(stringr)

string <- c("Y: 10 ,W: 3 , cp: 0.05","Y: 4 ,W: 9 , cp: 2.2")


vec <- t(str_split(str_split(string, " ,", simplify = TRUE), ": ", simplify = TRUE)[,2])

mtx = matrix( 
  vec, 
nrow = length(vec)/3, 
ncol = 3) 

colnames(mtx) <- c("Y","W","cp")

mtx

【讨论】:

    【解决方案2】:

    也许不是最优雅的方式,但它确实有效:

    library(dplyr)
    library(stringr)
    library(tidyr)
    tibble(row = c(1,2), 
           col = c("Y: 10 ,W: 3 , cp: 0.05","Y: 4 ,W: 9 , cp: 2.2")) %>%
      separate(col, into=c("col1", "col2", "col3"), sep = ",") %>%
      gather(id, col, -row) %>%
      select(-id) %>%
      mutate(col = str_trim(col)) %>%
      separate(col, into=c("letter", "number"), sep=":") %>%
      mutate(number = str_trim(number)) %>%
      spread(letter, number) %>%
      select(-row)
    
    # A tibble: 2 x 3
      cp    W     Y    
      <chr> <chr> <chr>
    1 0.05  3     10   
    2 2.2   9     4   
    

    请注意,我必须在您的数据框中添加一个名为 row 的新列才能使这种方法有效

    【讨论】:

    • 您能否将您的软件包列表限制在tidyverse 元软件包之下?有些人没有它可用(由于政策或偏好),因此最好具体说明使用您的答案所需的内容。在这种情况下,我怀疑它只是library(dplyr); library(tidyr); library(stringr),如果我错了,请纠正我。
    【解决方案3】:

    我发现有时将name: value 对数据重新格式化回现有结构有助于处理复杂性。在这种情况下,我已经格式化为 JSON 对象,然后使用 jsonlite 中的stream_in 来处理数据。

    这很好,因为它会自动命名列,并且还可以处理并非每个值都表示在每一行中或顺序发生变化的情况。例如:

    txt <- c(
      "Y: 10 ,W: 3 , cp: 0.05",
      "Y: 6 ,W: 7 , cp: 0.08",
      "cp: 0.08, Y: 6 "
    )
    
    library(jsonlite)
    proctxt <- paste("{", gsub("([A-Za-z]+?):", '"\\1":', txt), "}")
    stream_in(textConnection(proctxt))
    # Found 3 records...
    # Imported 3 records. Simplifying...
    #   Y  W   cp
    #1 10  3 0.05
    #2  6  7 0.08
    #3  6 NA 0.08
    

    【讨论】:

      【解决方案4】:

      您可以删除所有不需要的字符,例如使用gsub,然后使用strsplitread.csv。 在 base 中它看起来像:

      string <- c("Y: 10 ,W: 3 , cp: 0.05", "Y: 10 ,W: 3 , cp: 0.05")
      read.csv(text=gsub("[[:alpha:]: ]", "", string), header=FALSE)
      #  V1 V2   V3
      #1 10  3 0.05
      #2 10  3 0.05
      
      #or with strsplit
      strsplit(gsub("[[:alpha:]: ]", "", string), ",")
      

      【讨论】:

        【解决方案5】:

        鉴于您的文本字符串是统一的,它应该相对简单,第一部分如下所示:

        txt <- c(
          "Y: 10 ,W: 3 , cp: 0.05",
          "Y: 6 ,W: 7 , cp: 0.08",
          "Y: 5 ,W: 0 , cp: 0.08"
        )
        
        x <- do.call(rbind, strsplit(txt, split = " ,"))
        

        这将得到你的“标签:价值”的矩阵

        library(stringr)
        y <- matrix(data = str_extract(string = x,
                                       pattern = "([0-9.]+)"),
                    ncol = ncol(x))
        

        将为您提供表示您的值的文本字符串,如果您愿意,您可以使用 str_extract() 而不使用矩阵调用来获取您的值作为向量,并且:

        z <- matrix(data = as.numeric(y),
                    ncol = ncol(x))
        

        会将您的矩阵作为数字提供给您,这听起来像是您感兴趣的内容。

        总的来说,它相当整洁,并且没有中间矩阵调用,如果不需要,它看起来像:

        library(stringr)
        txt <- c(
          "Y: 10 ,W: 3 , cp: 0.05",
          "Y: 6 ,W: 7 , cp: 0.08",
          "Y: 5 ,W: 0 , cp: 0.08"
        )
        
        x <- do.call(rbind, strsplit(txt, split = " ,"))
        y <- str_extract(string = x,
                         pattern = "([0-9.]+)")
        z <- matrix(data = as.numeric(y),
                    ncol = ncol(x))
        

        z 给你一个数字矩阵。

        【讨论】:

          【解决方案6】:

          我相信这应该可行:

          library(tidyverse)
          
          
          string <- c("Y: 10 ,W: 3 , cp: 0.05","Y: 4 ,W: 9 , cp: 2.2")
          
          
          dat <- tibble(x = string) %>% 
            separate(x,c("Y","W","cp"), sep = " ,")
          
          
          dat2 <- dat %>% mutate_all(., ~str_remove(.,"\\D+"))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-10-29
            • 1970-01-01
            • 1970-01-01
            • 2020-11-10
            • 2017-01-07
            • 1970-01-01
            相关资源
            最近更新 更多