R如何从长格式转换为宽格式

问题描述 投票:1回答:1

我需要具有以下列的数据帧df_wide

userID   SAT   GRE   task_conf task_chall active_conf  active_chall  sleep_conf  sleep_chall morn_conf  morn_chall
30798    A     1400  2         3          5            2             6            1          4          2
30895    A     1200  6         2          5            3             5            2          5          3
32678    B     1000  5         3          6            3             6            2          5          2
34679    A     1300  4         3          4            2             6            1          6          3
35999    A     1400  2         2          2            2             2            2          2          2

有关功能的一些信息:

The variables '_conf' and '_chall' contain integer values between 1 and 6
'userID's can be factors or integers but they are not continuous numbers
SAT represents the grade of that 'userID'
GRE represents the score of that 'userID'
SAT and GRE always stay the same for a given 'userID' 

我的原始数据df_long当前采用以下格式:

userID SAT GRE  action ConfChall vals
30798  A   1400 task   conf      2
30798  A   1400 task   chall     3
30798  A   1400 active conf      5
30798  A   1400 active chall     2
30798  A   1400 sleep  conf      6
30798  A   1400 sleep  chall     1
30798  A   1400 morn   conf      4
30798  A   1400 morn   chall     2
30895  A   1200 task   conf      6
30895  A   1200 task   chall     2
30895  A   1200 active conf      5
30895  A   1200 active chall     3
30895  A   1200 sleep  conf      5
30895  A   1200 sleep  chall     2
30895  A   1200 morn   conf      5
30895  A   1200 morn   chall     3
32678  B   1000 task   conf      5
32678  B   1000 task   chall     3
32678  B   1000 active conf      6
32678  B   1000 active chall     3
32678  B   1000 sleep  conf      6
32678  B   1000 sleep  chall     2
32678  B   1000 morn   conf      5
32678  B   1000 morn   chall     2
34679  A   1300 task   conf      4
34679  A   1300 task   chall     3
34679  A   1300 active conf      4
34679  A   1300 active chall     2
34679  A   1300 sleep  conf      6
34679  A   1300 sleep  chall     1
34679  A   1300 morn   conf      6
34679  A   1300 morn   chall     3
35999  A   1400 task   conf      2
35999  A   1400 task   chall     2
35999  A   1400 active conf      2
35999  A   1400 active chall     2
35999  A   1400 sleep  conf      2
35999  A   1400 sleep  chall     2
35999  A   1400 morn   conf      2
35999  A   1400 morn   chall     2

我尝试使用以下代码,但在两种情况下输出均不正确。

library(reshape2)
df_wide = recast(df_long, userID ~ c('action','confChall','vals'),
          id.var = c("userID", "SAT", "GRE"))

df_wide = dcast(df_long, userID + SAT + GRE ~ c(action + ConfChall), value.var = "vals")

我试图遵循以下页面中的示例代码。但是我很难将这些应用于我的问题。任何对此的建议或意见,将不胜感激。

Reshape data from long to wide format - more than one variable

Reshape multiple values at once

r dplyr reshape reshape2
1个回答
2
投票

您可以使用pivot_wider程序包(属于tidyr程序包套件的一部分)中的tidyverse来重塑多个类别列和多个值列:

library(tidyverse)

df_wide = df_long %>% 
  pivot_wider(names_from=c(action, ConfChall), values_from=vals)
  userID SAT  GRE task_conf task_chall active_conf active_chall sleep_conf sleep_chall morn_conf morn_chall
1  30798   A 1400         2          3           5            2          6           1         4          2
2  30895   A 1200         6          2           5            3          5           2         5          3
3  32678   B 1000         5          3           6            3          6           2         5          2
4  34679   A 1300         4          3           4            2          6           1         6          3

reshape2是一个旧程序包,据我所知,已不再处于积极开发中,并且已被tidyverse程序包所取代。

为了解决您在注释中提到的警告:如果宽数据框中的任何单元格具有多个值,那么您将获得所得到的结果。如果您的用户ID,SAT,GRE,action和ConfChall的行多于同一行,或者通常是行和列类别的组合可能出现在多行中,则将发生这种情况。这不会在您的数据样本中发生,但是会在您的真实数据中发生。

因此,我们将重复的行添加到数据样本中:

df_long = read.table(text="userID SAT GRE  action ConfChall vals
30798  A   1400 task   conf      2
30798  A   1400 task   chall     3
30798  A   1400 task   chall     4 # added row to create a duplicate
30798  A   1400 active conf      5
30798  A   1400 active chall     2
30798  A   1400 sleep  conf      6
30798  A   1400 sleep  chall     1
30798  A   1400 morn   conf      4
30798  A   1400 morn   chall     2
30895  A   1200 task   conf      6
30895  A   1200 task   chall     2
30895  A   1200 active conf      5
30895  A   1200 active chall     3
30895  A   1200 sleep  conf      5
30895  A   1200 sleep  chall     2
30895  A   1200 morn   conf      5
30895  A   1200 morn   chall     3
32678  B   1000 task   conf      5
32678  B   1000 task   chall     3
32678  B   1000 active conf      6
32678  B   1000 active chall     3
32678  B   1000 sleep  conf      6
32678  B   1000 sleep  chall     2
32678  B   1000 morn   conf      5
32678  B   1000 morn   chall     2
34679  A   1300 task   conf      4
34679  A   1300 task   chall     3
34679  A   1300 active conf      4
34679  A   1300 active chall     2
34679  A   1300 sleep  conf      6
34679  A   1300 sleep  chall     1
34679  A   1300 morn   conf      6
34679  A   1300 morn   chall     3", header=TRUE)

现在让我们重塑以扩大。请注意,我们得到警告,并且列表列单元格之一具有两个值而不是一个:

df_long %>% 
  pivot_wider(names_from=c(action, ConfChall), values_from=vals)

Warning message:
Values in `vals` are not uniquely identified; output will contain list-cols.
* Use `values_fn = list(vals = list)` to suppress this warning.
* Use `values_fn = list(vals = length)` to identify where the duplicates arise
* Use `values_fn = list(vals = summary_fun)` to summarise duplicates 
  userID SAT     GRE   task_conf  task_chall active_conf active_chall  sleep_conf sleep_chall   morn_conf  morn_chall
   <int> <fct> <int> <list<int>> <list<int>> <list<int>>  <list<int>> <list<int>> <list<int>> <list<int>> <list<int>>
1  30798 A      1400         [1]         [2]         [1]          [1]         [1]         [1]         [1]         [1]
2  30895 A      1200         [1]         [1]         [1]          [1]         [1]         [1]         [1]         [1]
3  32678 B      1000         [1]         [1]         [1]          [1]         [1]         [1]         [1]         [1]
4  34679 A      1300         [1]         [1]         [1]          [1]         [1]         [1]         [1]         [1]

要获得常规数据帧,可以使用unnest()。请注意,现在有五行,用户ID 30798出现了两次:

df_long %>% 
  pivot_wider(names_from=c(action, ConfChall), values_from=vals) %>% 
  unnest()
  userID SAT     GRE task_conf task_chall active_conf active_chall sleep_conf sleep_chall morn_conf morn_chall
   <int> <fct> <int>     <int>      <int>       <int>        <int>      <int>       <int>     <int>      <int>
1  30798 A      1400         2          3           5            2          6           1         4          2
2  30798 A      1400         2          4           5            2          6           1         4          2
3  30895 A      1200         6          2           5            3          5           2         5          3
4  32678 B      1000         5          3           6            3          6           2         5          2
5  34679 A      1300         4          3           4            2          6           1         6          3

如果要以某种方式汇总重复的行,以便行和列变量的每个组合仅获得一行,则可以应用摘要函数。下面,我们取每个单元的平均值,在这种情况下,它仅影响具有两行数据的一次单元:

df_long %>% 
  pivot_wider(names_from=c(action, ConfChall), values_from=vals,
              values_fn=list(vals=mean))
  userID SAT     GRE task_conf task_chall active_conf active_chall sleep_conf sleep_chall morn_conf morn_chall
   <int> <fct> <int>     <dbl>      <dbl>       <dbl>        <dbl>      <dbl>       <dbl>     <dbl>      <dbl>
1  30798 A      1400         2        3.5           5            2          6           1         4          2
2  30895 A      1200         6        2             5            3          5           2         5          3
3  32678 B      1000         5        3             6            3          6           2         5          2
4  34679 A      1300         4        3             4            2          6           1         6          3
© www.soinside.com 2019 - 2024. All rights reserved.