【问题标题】:Pivot Key-Value Table to Tidy Data Frame in R在 R 中将键值表透视到整洁的数据框
【发布时间】:2020-09-28 00:05:42
【问题描述】:

我有一个格式如下的数据框:

df_before <- 
  tibble(
    key = rep(c('rank', 'name', 'metric'), 5), 
    value = c(
      1, 'name1', 4352, 
      2, 'name2', 2181, 
      3, 'name3', 1399, 
      4, 'name4', 1087, 
      5, 'name5', 1010
    ))

# A tibble: 15 x 2
   key    value
   <chr>  <chr>
 1 rank   1    
 2 name   name1
 3 metric 4352 
 4 rank   2    
 5 name   name2
 6 metric 2181 
 7 rank   3    
 8 name   name3
 9 metric 1399 
10 rank   4    
11 name   name4
12 metric 1087 
13 rank   5    
14 name   name5
15 metric 1010 

我需要把它变成这种格式:

df_after <- 
  tibble(
    rank = 1:5, 
    name = c('name1', 'name2', 'name3', 'name4', 'name5'), 
    metric = c(4352, 2181, 1399, 1087, 1010)
    )

# A tibble: 5 x 3
   rank name  metric
  <int> <chr>  <dbl>
1     1 name1   4352
2     2 name2   2181
3     3 name3   1399
4     4 name4   1087
5     5 name5   1010

我知道tidyr 中有枢轴函数,但我无法从文档中找出语法。 Tidyverse 是首选,但任何库或基本函数都可以。

【问题讨论】:

    标签: r pivot tidyr melt


    【解决方案1】:

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

    unstack(df_before,value~key)
    
      metric  name rank
    1   4352 name1    1
    2   2181 name2    2
    3   1399 name3    3
    4   1087 name4    4
    5   1010 name5    5
    

    要将类型转换为整数/双精度,您可以这样做:

    type.convert(unstack(df_before,value~key))
    

    【讨论】:

      【解决方案2】:

      data.table 中我们可以使用dcast

      library(data.table)
      dcast(setDT(df_before), rowid(key)~key, value.var = 'value')[, key:= NULL][]
      
      #   metric  name rank
      #1:   4352 name1    1
      #2:   2181 name2    2
      #3:   1399 name3    3
      #4:   1087 name4    4
      #5:   1010 name5    5
      

      【讨论】:

        【解决方案3】:

        我们可以创建一个序列列然后执行pivot_wider

        library(dplyr)
        library(tidyr)
        library(data.table)
        df_before %>% 
           mutate(rn = rowid(key)) %>% 
           pivot_wider(names_from = key, values_from = value) %>%
           select(-rn) %>%
           type.convert(as.is = TRUE)
        # A tibble: 5 x 3
        #   rank name  metric
        #  <int> <chr>  <int>
        #1     1 name1   4352
        #2     2 name2   2181
        #3     3 name3   1399
        #4     4 name4   1087
        #5     5 name5   1010
        

        或带有group_split的选项

        df_before %>%
            group_split(key = factor(key, levels = unique(key)), .keep = FALSE) %>% 
            bind_cols %>% 
            set_names(unique(df_before$key)
        

        或使用base R

        data.frame(split(df_before$value, df_before$key))
        #  metric  name rank
        #1   4352 name1    1
        #2   2181 name2    2
        #3   1399 name3    3
        #4   1087 name4    4
        #5   1010 name5    5
        

        【讨论】:

          猜你喜欢
          • 2020-05-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多