【问题标题】:how to split a string column in R based on equal length and get them in different rows如何根据相等的长度拆分R中的字符串列并将它们放在不同的行中
【发布时间】:2020-04-17 11:11:25
【问题描述】:
library(tidyr)
library(dplyr)

mydf

  V1    V2
2  1 abcdef
3  2   abcd
4  3   bghj
5  4   kl
6  5    uilm

我想让我的数据框在结果 V2 列中以 2 的长度分隔在单独的行中

   V1 V2
1   1  ab
2   1  cd
3   1  ef
4   2  ab
5   2  cd
6   3  bg
7   3  hj
8   4  kl
9   5  ui
10  5  lm

【问题讨论】:

    标签: r strsplit


    【解决方案1】:

    这是一个基本的 R 选项,每 2 个字符拆分一次字符串 -

    mydf <- data.frame(V1 = 1:5, V2 = c('abcdef', 'abcd', 'bghj', 'kl', 'ulim'))
    
    tmp <- strsplit(mydf$V2, '(?<=..)', perl = TRUE)
    result <- mydf[rep(1:nrow(mydf), lengths(tmp)), ]
    result$V2 <- unlist(tmp)
    rownames(result) <- NULL
    result
    
    #   V1 V2
    #1   1 ab
    #2   1 cd
    #3   1 ef
    #4   2 ab
    #5   2 cd
    #6   3 bg
    #7   3 hj
    #8   4 kl
    #9   5 ul
    #10  5 im
    

    【讨论】:

      【解决方案2】:

      另一种 tidyverse 方法。基本上它添加了一些额外的字符,例如@,这些字符可能不会出现在其他地方,然后使用tidyr::separate_rows

      
      library(tidyverse)
      df %>% mutate(V2 = map_chr(strsplit(V2, '(?<=..)', perl = T), ~paste(.x, collapse = '@'))) %>%
        separate_rows(V2)
      #> # A tibble: 10 x 2
      #>       V1 V2   
      #>    <int> <chr>
      #>  1     1 ab   
      #>  2     1 cd   
      #>  3     1 ef   
      #>  4     2 ab   
      #>  5     2 cd   
      #>  6     3 bg   
      #>  7     3 hj   
      #>  8     4 kl   
      #>  9     5 ul   
      #> 10     5 im
      

      reprex package (v2.0.0) 于 2021-06-04 创建

      【讨论】:

        【解决方案3】:

        您也可以使用以下解决方案:

        library(dplyr)
        library(tidyr)
        library(stringr)
        
        df %>%
          rowwise() %>%
          mutate(V2 = list(str_sub(V2, seq(1, nchar(V2)-1, 2), seq(2, nchar(V2), 2)))) %>%
          unnest_longer(col = V2)
        
        # A tibble: 10 x 2
              V1 V2   
           <int> <chr>
         1     1 ab   
         2     1 cd   
         3     1 ef   
         4     2 ab   
         5     2 cd   
         6     3 bg   
         7     3 hj   
         8     4 kl   
         9     5 ui   
        10     5 lm
        

        【讨论】:

          【解决方案4】:

          您可以定义一个函数来对每个其他字符进行子字符串化,并将其逐行应用于V2 以创建字符向量的嵌套列。然后,取消嵌套列。

          library(tidyverse)
          
          mydf <- read.table(
            text = "
              V1    V2
            1 abcdef
            2   abcd
            3   bghj
            4   kl
            5    uilm",
            header = TRUE
          )
          
          get_string <- function(str) {
            n <- seq(1, nchar(str), 2)
            map_chr(n, ~ str_sub(str, ., . + 1))
          }
          
          mydf %>% 
            rowwise() %>% 
            mutate(V2 = list(get_string(V2))) %>% 
            ungroup() %>% 
            unnest(V2)
          
          # # A tibble: 10 x 2
          #       V1 V2   
          #    <int> <chr>
          #  1     1 ab   
          #  2     1 cd   
          #  3     1 ef   
          #  4     2 ab   
          #  5     2 cd   
          #  6     3 bg   
          #  7     3 hj   
          #  8     4 kl   
          #  9     5 ui   
          # 10     5 lm   
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-08-11
            • 2022-12-09
            • 2020-02-06
            • 2022-11-18
            • 2021-10-26
            • 1970-01-01
            相关资源
            最近更新 更多