【问题标题】:Flatten data frame and shift rows to columns展平数据框并将行移到列
【发布时间】:2018-03-08 22:31:31
【问题描述】:

我有一个像这样的数据框:

df <- data.frame(
  id = c(1, 1, 2, 2), 
  V1 = c(1:4), 
  V2 = c(5:8), 
  V3 = c(9:12))

打印到控制台看起来像这样:

#   id V1 V2 V3
# 1  1  1  5  9
# 2  1  2  6 10
# 3  2  3  7 11
# 4  2  4  8 12

现在,我想把它变成这个形状:

#   id V1 V2 V3 V4 V5 V6
# 1  1  1  5  9  2  6 10
# 2  2  3  7 11  4  8 12

如何使用基本 R 或 tidyverse 来做到这一点?

【问题讨论】:

    标签: r dataframe tidyverse


    【解决方案1】:

    一个可能的tidyverse 解决方案

    wide <- df %>%
      group_by(id) %>%
      mutate(obs = row_number()) %>%
      gather(var, val, V1:V3) %>%
      unite(comb, obs, var) %>%
      spread(comb, val)
    
    colnames(wide)[-1] <- paste("V", seq(1,ncol(wide) -1), sep = "")
    
    # A tibble: 2 x 7
    # Groups:   id [2]
    #     id    V1    V2    V3    V4    V5    V6
    #1     1     1     5     9     2     6    10
    #2     2     3     7    11     4     8    12
    

    【讨论】:

      【解决方案2】:

      您可以使用例如使用by。

      df2 <- do.call(rbind,
        by(df, df$id, function(x) c(x[1, "id"], as.vector(t(x[names(x) != "id"]))))
        )
      
      colnames(df2) <- c("id", paste0("V", seq(ncol(df2)-1)))
      
        id V1 V2 V3 V4 V5 V6
      1  1  1  5  9  2  6 10
      2  2  3  7 11  4  8 12
      

      【讨论】:

        【解决方案3】:

        基础R:

        lists <- Map(function(x) data.frame(c(x[1,], x[2,-1])), split(df, df$id))
        df2   <- do.call(rbind, lists)
        

        更改列名:

        colnames(df2) <- c("id", paste0("V", seq_along(df2[-1])))
        

        结果:

        # > df2
        #   id V1 V2 V3 V4 V5 V6
        # 1  1  1  5  9  2  6 10
        # 2  2  3  7 11  4  8 12
        

        【讨论】:

          猜你喜欢
          • 2018-11-09
          • 1970-01-01
          • 1970-01-01
          • 2014-10-15
          • 2021-07-02
          • 2022-09-22
          • 2022-06-13
          • 2019-01-10
          • 1970-01-01
          相关资源
          最近更新 更多