【问题标题】:How to transform from long to wide data set in r by creating means如何通过创建手段将r中的长数据集转换为宽数据集
【发布时间】:2020-09-05 02:58:05
【问题描述】:

我有以下数据集:

    Email           Relationship      Q1  Q2  Q3  Q4
1  sample@email.com    Self           1   2    2   3
2  sample@email.com    Peer           3   3    4   5
3  sample@email.com    Peer           5   2    3   1
4  sample@email.com    Peer           4   1    2   3
5  sample@email.com    Peer           2   3    3   4
6  sample@email.com    Direct Report  3   3    4   4   
7  sample@email.com    Direct Report  5   2    4   4
8  other@email.com     Self           3   4    4   2
9  other@email.com     Peer           2   2    3   4
10 other@email.com     Peer           3   3    3   2
11 other@email.com     Peer           2   5    5   3
12 other@email.com     Direct Report  4   4    4   3
13 other@email.com     Direct Report  5   3    2   1 
14 other@email.com     Direct Report  2   4    5   3

我想将它从长转换为宽,这样我就可以计算每个关系组和总计的平均值:

Email            Q1-Overall Q1-Self  Q1-Peer  Q1-Direct Report  Q2-Overall Q2-Self  Q2-Peer  Q2-Direct Report
other@email.com   3.00      3.00      2.33     3.67             3.57       4.00     3.33     3.67
sample@email.com  3.29      1.00      3.50     4.00             2.28       2.00     2.25     2.50

我试过融化它:

df<-dcast(melt(Data_Long, id.vars=c("Email", "Relationship")), Email~Q1+Relationship)

这让我成功了,但我的问题是如何将它带到下一步以获得手段,或者是否有更有效的方法。由于我的数据有数百个问题,有没有办法有效地转换所有问题?

我还尝试了 dplyr 包汇总和传播命令,但无法找到一种方法来组合变量以在其中创建新变量。任何建议表示赞赏。

【问题讨论】:

  • 为什么不先使用aggregateby 计算均值?一旦你有办法,你可以将其转换为宽格式。你试过了吗?
  • 你很亲密。 dcast 有一个 fun.aggregate 参数,您可以在这里使用:library(reshape2); dcast(melt(Data_Longt, measure.vars = paste0("Q", 1:4)), Email ~ paste(Relationship, variable, sep = "-"), fun.aggregate = mean) ..
  • .. 部分~ paste(Relationship, variable, sep = "-") 真的很方便恕我直言。

标签: r dataframe aggregate reshape


【解决方案1】:

这是tidyverse 解决方案。它按EmailRelationship 分组以计算列Q* 均值。然后它使用pivot_wider 重塑为宽格式。

library(tidyverse)

Data_long %>%
  group_by(Email, Relationship) %>%
  summarise_at(vars(matches('^Q')), list(mean)) %>%
  pivot_wider(
    id_cols = Email,
    names_from = Relationship,
    values_from = matches('^Q')
  )
## A tibble: 2 x 13
## Groups:   Email [2]
#  Email `Q1_Direct Repo… Q1_Peer Q1_Self `Q2_Direct Repo… Q2_Peer Q2_Self `Q3_Direct Repo…
#  <chr>            <dbl>   <dbl>   <dbl>            <dbl>   <dbl>   <dbl>            <dbl>
#1 othe…             3.67    2.33       3             3.67    3.33       4             3.67
#2 samp…             4       3.5        1             2.5     2.25       2             4   
## … with 5 more variables: Q3_Peer <dbl>, Q3_Self <dbl>, #`Q4_Direct Report` <dbl>,
##   Q4_Peer <dbl>, Q4_Self <dbl>

数据。

Data_long <- read.table(text = "
    Email           Relationship      Q1  Q2  Q3  Q4
1  sample@email.com    Self           1   2    2   3
2  sample@email.com    Peer           3   3    4   5
3  sample@email.com    Peer           5   2    3   1
4  sample@email.com    Peer           4   1    2   3
5  sample@email.com    Peer           2   3    3   4
6  sample@email.com    'Direct Report'  3   3    4   4   
7  sample@email.com    'Direct Report'  5   2    4   4
8  other@email.com     Self           3   4    4   2
9  other@email.com     Peer           2   2    3   4
10 other@email.com     Peer           3   3    3   2
11 other@email.com     Peer           2   5    5   3
12 other@email.com     'Direct Report'  4   4    4   3
13 other@email.com     'Direct Report'  5   3    2   1 
14 other@email.com     'Direct Report'  2   4    5   3
", header = TRUE)

【讨论】:

    【解决方案2】:

    data.table 解决方案:

    library(data.table)
    setDT(df)
    df[, melt(.SD, id.vars = c("Email", "Relationship"))
       ][, dcast(.SD, Email ~ paste(variable, Relationship, sep = "-"), fun.aggregate = mean)]
    
                  Email Q1-Direct Report  Q1-Peer Q1-Self Q2-Direct Report  Q2-Peer Q2-Self Q3-Direct Report  Q3-Peer Q3-Self Q4-Direct Report Q4-Peer Q4-Self
    1:  other@email.com         3.666667 2.333333       3         3.666667 3.333333       4         3.666667 3.666667       4         2.333333    3.00       2
    2: sample@email.com         4.000000 3.500000       1         2.500000 2.250000       2         4.000000 3.000000       2         4.000000    3.25       3
    

    数据(下次请自行提供)

    df <- data.frame(
      Email = rep(c("sample@email.com", "other@email.com"), each = 7L), 
      Relationship = c(
        "Self", "Peer", "Peer", "Peer", "Peer", "Direct Report", 
        "Direct Report", "Self", "Peer", "Peer", "Peer", "Direct Report", 
        "Direct Report", "Direct Report"
      ), 
      Q1 = c(1L, 3L, 5L, 4L, 2L, 3L, 5L, 3L, 2L, 3L, 2L, 4L, 5L, 2L), 
      Q2 = c(2L, 3L, 2L, 1L, 3L, 3L, 2L, 4L, 2L, 3L, 5L, 4L, 3L, 4L), 
      Q3 = c(2L, 4L, 3L, 2L, 3L, 4L, 4L, 4L, 3L, 3L, 5L, 4L, 2L, 5L), 
      Q4 = c(3L, 5L, 1L, 3L, 4L, 4L, 4L, 2L, 4L, 2L, 3L, 3L, 1L, 3L)
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-29
      • 2022-01-22
      • 2020-08-11
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 2019-07-23
      相关资源
      最近更新 更多