R如何从长格式转换为宽格式
R how to convert from long to wide format
我需要一个包含以下列的数据框 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 multiple values at once
您可以使用 tidyr
包(tidyverse
包套件的一部分)中的 pivot_wider
重塑多个类别列和多个值列:
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
软件包取代。
解决您在评论中提到的警告:如果宽数据框中的任何单元格具有多个值,那么您将得到您得到的结果。如果有多行具有相同的 userID、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
我需要一个包含以下列的数据框 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 multiple values at once
您可以使用 tidyr
包(tidyverse
包套件的一部分)中的 pivot_wider
重塑多个类别列和多个值列:
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
软件包取代。
解决您在评论中提到的警告:如果宽数据框中的任何单元格具有多个值,那么您将得到您得到的结果。如果有多行具有相同的 userID、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