【问题标题】:How to combine two rows of a dataframe into one row如何将数据框的两行合并为一行
【发布时间】:2022-07-20 23:28:36
【问题描述】:

我有一个看起来像这样的数据框。

 Name  info.1 info.2 
  ab      a      1
  123     a      1
  de      c      4
  456     c      4
  fg      d      5
  789     d      5 

除了名称列之外,需要合并的两行是相同的,并且在数据框中是一起的。我希望新的数据框看起来像这样:

 Name ID  info.1 info.2 
  ab  123    a      1
  de  456    c      4
  fg  789    d      5
  

我不知道该怎么做,到目前为止谷歌搜索也没有帮助

【问题讨论】:

    标签: r


    【解决方案1】:

    一个可能的解决方案:

    library(tidyverse)
    
    df %>% 
      group_by(info.1) %>% 
      summarise(Name = str_c(Name, collapse = "_"), info.2 = first(info.2)) %>% 
      separate(Name, into = c("Name", "ID"), convert = T) %>% 
      relocate(info.1, .before = info.2)
    
    #> # A tibble: 3 × 4
    #>   Name     ID info.1 info.2
    #>   <chr> <int> <chr>   <int>
    #> 1 ab      123 a           1
    #> 2 de      456 c           4
    #> 3 fg      789 d           5
    

    【讨论】:

      【解决方案2】:

      在基础 R 中你可以这样做:

      data.frame(Name = df[seq(nrow(df)) %% 2 == 0, 1], 
                 ID   = df[seq(nrow(df)) %% 2 == 1, 1],
                 df[seq(nrow(df)) %% 2 == 0, 2:3])
      #>   Name  ID info.1 info.2
      #> 2   ab 456      a      1
      #> 4  123  fg      c      4
      #> 6   de 789      d      5
      

      reprex package (v2.0.1) 于 2022-07-20 创建

      【讨论】:

        【解决方案3】:

        假设 Name 列的顺序是一致的 Name-ID-Name-ID 那么:

        library(tidyverse)
        data <- tibble(Name = c('ab', 123, 'de', 456, 'fg', 789),
                       info.1 = c('a', 'a', 'c', 'c', 'd', 'd'),
                       info.2 = c(1, 1, 4, 4, 5, 5))
        
        # remove the troublesome column and make a tibble
        # with the unique combos of info1 and 2
        data_2 <- data %>% select(info.1, info.2) %>% distinct()
        
        # add columns for name and ID by skipping every other row in the
        # original tibble
        data_2$Name <- data$Name[seq(from = 1, to = nrow(data), by = 2)]
        data_2$ID <- data$Name[seq(from = 2, to = nrow(data), by = 2)]
        

        【讨论】:

          【解决方案4】:

          我们还可以使用summarise 并提取first 作为名称和last 作为id:

          data |>
            group_by(info.1, info.2) |>
            summarise(name = first(Name), ID = last(Name)) |>
            ungroup() #|>
            #relocate(3:4,1:2)
          

          输出:

          # A tibble: 3 × 4
            info.1 info.2 name  ID   
            <chr>   <dbl> <chr> <chr>
          1 a           1 ab    123  
          2 c           4 de    456  
          3 d           5 fg    789  
          

          【讨论】:

            【解决方案5】:

            我们也可以使用

            library(dplyr)
            library(stringr)
            data %>% 
              group_by(across(starts_with('info'))) %>% 
              mutate(ID = str_subset(Name, "^\\d+$"), .before = 2) %>% 
              ungroup %>%
              filter(str_detect(Name, '^\\d+$', negate = TRUE))
            

            -输出

            # A tibble: 3 × 4
              Name  ID    info.1 info.2
              <chr> <chr> <chr>   <dbl>
            1 ab    123   a           1
            2 de    456   c           4
            3 fg    789   d           5
            

            数据

            data <- structure(list(Name = c("ab", "123", "de", "456", "fg", "789"
            ), info.1 = c("a", "a", "c", "c", "d", "d"), info.2 = c(1, 1, 
            4, 4, 5, 5)), row.names = c(NA, -6L), class = "data.frame")
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-03-10
              • 2022-12-18
              • 1970-01-01
              • 1970-01-01
              • 2021-09-10
              • 2015-02-08
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多