【问题标题】:Rearranging / dataframe in R在R中重新排列/数据框
【发布时间】:2021-07-22 15:32:00
【问题描述】:

我有一个如下所示的 excel 文件:

ID strength_score_week_1 agility_score_week_1 strength_score_week_2 agility_score_week_2
1 3 6 4 6
2 5 6 6 6
3 8 8 9 8
4 6 7 6 4

我想把上面的数据重新排列/重写成一个数据框,把它排列成这种格式:

Week training type mean score
1 agility
1 strength
2 agility
2 strength

我想对决赛桌做的基本上是 - 我想按训练类型对其进行分组并绘制 2 个折线图,显示 40 周内敏捷性和力量的平均得分

任何帮助将不胜感激!

【问题讨论】:

    标签: r dataframe tidyverse


    【解决方案1】:
    df <- data.frame(
                         ID = c(1L, 2L, 3L, 4L),
      strength_score_week_1 = c(3L, 5L, 8L, 6L),
       agility_score_week_1 = c(6L, 6L, 8L, 7L),
      strength_score_week_2 = c(4L, 6L, 9L, 6L),
       agility_score_week_2 = c(6L, 6L, 8L, 4L)
          )
    df
    #>   ID strength_score_week_1 agility_score_week_1 strength_score_week_2
    #> 1  1                     3                    6                     4
    #> 2  2                     5                    6                     6
    #> 3  3                     8                    8                     9
    #> 4  4                     6                    7                     6
    #>   agility_score_week_2
    #> 1                    6
    #> 2                    6
    #> 3                    8
    #> 4                    4
    library(tidyverse)
    
    df %>% 
      pivot_longer(!ID, names_pattern = '([^_]*)_score_week_(.*)', names_to = c('training_type', 'week')) %>%
      group_by(week, training_type) %>%
      summarise(mean_score = mean(value), .groups = 'drop') %>%
      mutate(week = as.numeric(week)) %>%
      ggplot(aes(x = week, y = mean_score, color = training_type, group = training_type)) +
      geom_line()
    

    reprex package (v2.0.0) 于 2021 年 7 月 22 日创建

    【讨论】:

    • 我按照您的建议进行了尝试 - 做了我认为的技巧,但是当延长到 40 周时,x 轴的排序不正确。关于如何克服这个问题的任何提示?把有问题的图片供你参考
    • pivot_longergroup_by 之间执行此操作:mutate(week = as.numeric(week)) %&gt;%
    • @fireplush,是的,我忘了编辑这个。立即查看
    【解决方案2】:

    试试这个

    library(readxl) #library to import excel sheets
    
    df <- t(read_excel('Book1.xlsx')[,-1]) #import data (remove id column)
    
    df_mean <- rowMeans(df) #calculate mean score
    
    #get auxiliar matrix with names of elements
    aux <- matrix(unlist(strsplit(rownames(df), '_')), nrow = nrow(df), byrow = T)[,c(1,4)]
    colnames(aux) <- c('feature', 'week')
    
    #Join everything in a data frame
    df <- as.data.frame(cbind(df_mean, aux))
    
    #plot
    library(ggplot2)
    ggplot(df)+
      geom_point(aes(x = week, y = df_mean, colour = factor(feature)))
    

    【讨论】:

      【解决方案3】:
      library(dplyr)
      library(tibble)
      library(stringr)
      
      dt <- as.data.frame(t(dt))[-1,]
      dt %>%
        rownames_to_column() %>%
        rowwise() %>%
        mutate(`training type` = str_split(rowname, "_")[[1]][1],
               week = str_split(rowname, "_")[[1]][4]) %>%
        ungroup() %>%
        mutate(`mean score` = rowMeans(.[,2:5])) %>%
        select(week, `training type`, `mean score`)
      

      哪些结果:

      # A tibble: 4 x 3
        week  `training type` `mean score`
        <chr> <chr>                  <dbl>
      1 1     strength                5.5 
      2 1     agility                 6.75
      3 2     strength                6.25
      4 2     agility                 6   
      

      如果您的训练类型包含多个单词,您将使用不同的函数而不是 str_split。如果是这样,我可以重写那部分代码

      【讨论】:

        【解决方案4】:

        基本 R 选项

        do.call(
            rbind,
            apply(
                aggregate(
                    cbind(strength, agility) ~ time,
                    reshape(
                        setNames(df, gsub("_score_", ".", names(df))),
                        direction = "long",
                        idvar = "ID",
                        varying = -1
                    ), mean
                ), 1, function(x) cbind(week = x[[1]], rev(stack(x[-1])))
            )
        )
        

        给予

            week      ind values
        1 week_1 strength   5.50
        2 week_1  agility   6.75
        3 week_2 strength   6.25
        4 week_2  agility   6.00
        

        【讨论】:

          【解决方案5】:

          我会以这种方式混合使用pivot_longerseperatemutate

          data %>% 
                  pivot_longer(cols = -"ID", names_to = "training_type") %>%
                  mutate(training_type = str_remove(training_type, "_score")) %>%
                  group_by(training_type) %>%
                  summarise(mean_score = mean(value, na.rm = TRUE)) %>%
                  separate(
                          col = "training_type",
                          sep = "_week_",
                          into = c("training_type", "week")
                  ) %>%
                  mutate(week = as.numeric(week))
          

          这为您提供以下output

          # A tibble: 4 x 3
            training_type  week mean_score
            <chr>         <dbl>      <dbl>
          1 agility           1       6.75
          2 agility           2       6   
          3 strength          1       5.5 
          4 strength          2       6.25
          

          准备好被谁绘制,

          data %>% ggplot(
                  mapping = aes(
                          x = week,
                          y = mean_score,
                          color = training_type
                  )
          ) + geom_line() 
          

          【讨论】:

            猜你喜欢
            • 2013-07-03
            • 2012-10-01
            • 2014-06-23
            • 2015-09-25
            • 1970-01-01
            • 2018-07-18
            • 2013-10-21
            • 1970-01-01
            相关资源
            最近更新 更多