收集/熔化多个列集,变量列的整数值?
Gathering/ melting multiple column sets, integer values for the variable column?
首先,很抱歉,我知道我的问题与这里的其他几个问题重叠,但我对 R 真的很陌生,我找不到完全完成任务的答案,而且我实际上可以明白了。
我的数据集是这样的:
ID … Exam_t_minus_3 Exam_t_minus_2 Exam_t_minus_1 Grade_2012 Grade_2013 Grade_2014
1 Math Physics Chemestry 98 70 76
2 English French Russian 77 85 59
3 English Chemistry Biology 65 77 69
我希望它变成这样的东西:
ID … i(as t_minus_i_) Exam Grade
1 3 Math 98
1 2 Physics 70
1 1 Chemistry 76
2 3 English 77
2 2 French 85
2 1 Russian 59
我已经学习了 swirl() 课程并认为我可以使用 tidyr 来完成,但我不知道如何收集不止一组列。我最终得到了这样的结果:
ID … ................ Exam Grade
1 . Math 98
1 . Math 70
1 . Math 76
1 . Physics 98
1 . Physics 70
1 . Physics 76
我调查了这个:Gather multiple sets of columns 和其他一些人,但大多数人半途而废。
我也试过这个问题的答案(我把收入栏改成预先以T_minus_*结尾):
我试过了
library(data.table)
res = melt(setDT(sample_df),
measure.vars = patterns("^Exam", "^Grade"),
variable.name = "i")
res[, i := factor(i, labels = c("3","2", "1"))]
它完成了我需要的大部分事情,但是,我需要我的 i 列中的值是整数而不是分类变量,因为我需要它们用于未来的计算。
我尝试这样做 res$i <- as.numeric(res$i)
,但是这改变了顺序,即“3”被计算为 1,“1”被计算为 3。
我试图将其排除在外,但这也为我提供了 1、2、3 以及 i 列值。
当我将收益列更改为 Earnings_T_minus_* 时,我能否以某种方式在 i 列中获取这些 * 值?
library(data.table)
res = melt(setDT(sample_df),
measure.vars = patterns("^Exam_T_minus_*", "^Grade_T_minus_*"),
variable.name = "i")
抱歉,这个问题变得有点长而且可能令人困惑,但希望有人能指引我正确的方向。
使用 dplyr
和 tidyr
的解决方案。
需要两次gather
过程。第一次,我们可以收集 i(as t_minus_i_)
和 Exam
。第二次,我们可以收集 Year
和 Grade
.
starts_with
是一个辅助函数,可以 select 以字符串开头的列。 sub
是将字符串替换为空字符串"",进一步格式化列。 as.integer
是将字符数转换为整数。 dt2
是最终输出。
library(dplyr)
library(tidyr)
dt2 <- dt %>%
# First gather process: gather the i(as t_minus_i_) and Exam
gather(`i(as t_minus_i_)`, Exam, starts_with("Exam")) %>%
mutate(`i(as t_minus_i_)` = as.integer(sub("Exam_t_minus_", "", `i(as t_minus_i_)`))) %>%
# Second gather process: gather the Grade
gather(Year, Grade, starts_with("Grade")) %>%
mutate(Year = as.integer(sub("Grade_", "", Year))) %>%
arrange(ID)
dt2
# ID i(as t_minus_i_) Exam Year Grade
# 1 1 3 Math 2012 98
# 2 1 2 Physics 2012 98
# 3 1 1 Chemestry 2012 98
# 4 1 3 Math 2013 70
# 5 1 2 Physics 2013 70
# 6 1 1 Chemestry 2013 70
# 7 1 3 Math 2014 76
# 8 1 2 Physics 2014 76
# 9 1 1 Chemestry 2014 76
# 10 2 3 English 2012 77
# 11 2 2 French 2012 77
# 12 2 1 Russian 2012 77
# 13 2 3 English 2013 85
# 14 2 2 French 2013 85
# 15 2 1 Russian 2013 85
# 16 2 3 English 2014 59
# 17 2 2 French 2014 59
# 18 2 1 Russian 2014 59
# 19 3 3 English 2012 65
# 20 3 2 Chemistry 2012 65
# 21 3 1 Biology 2012 65
# 22 3 3 English 2013 77
# 23 3 2 Chemistry 2013 77
# 24 3 1 Biology 2013 77
# 25 3 3 English 2014 69
# 26 3 2 Chemistry 2014 69
# 27 3 1 Biology 2014 69
数据
dt <- read.table(text = "ID Exam_t_minus_3 Exam_t_minus_2 Exam_t_minus_1 Grade_2012 Grade_2013 Grade_2014
1 Math Physics Chemestry 98 70 76
2 English French Russian 77 85 59
3 English Chemistry Biology 65 77 69",
header = TRUE, stringsAsFactors = FALSE)
您的 data.table
方法几乎是正确的。使用多列重塑是可行的方法。
library(data.table)
melt(setDT(sample_df),
measure.vars = patterns("^Exam", "^Grade"), value.name = c("Exam", "Grade"),
variable.name = "i", variable.factor = FALSE)[
, i := 4L - as.integer(i)][order(ID)]
ID i Exam Grade
1: 1 3 Math 98
2: 1 2 Physics 70
3: 1 1 Chemistry 76
4: 2 3 English 77
5: 2 2 French 85
6: 2 1 Russian 59
7: 3 3 English 65
8: 3 2 Chemistry 77
9: 3 1 Biology 69
唯一的修改是将 variable.factor = FALSE
作为参数传递给 melt()
,在强制转换为整数后对 i
进行一些算术运算,并适当地 order()
结果。
首先,很抱歉,我知道我的问题与这里的其他几个问题重叠,但我对 R 真的很陌生,我找不到完全完成任务的答案,而且我实际上可以明白了。
我的数据集是这样的:
ID … Exam_t_minus_3 Exam_t_minus_2 Exam_t_minus_1 Grade_2012 Grade_2013 Grade_2014
1 Math Physics Chemestry 98 70 76
2 English French Russian 77 85 59
3 English Chemistry Biology 65 77 69
我希望它变成这样的东西:
ID … i(as t_minus_i_) Exam Grade
1 3 Math 98
1 2 Physics 70
1 1 Chemistry 76
2 3 English 77
2 2 French 85
2 1 Russian 59
我已经学习了 swirl() 课程并认为我可以使用 tidyr 来完成,但我不知道如何收集不止一组列。我最终得到了这样的结果:
ID … ................ Exam Grade
1 . Math 98
1 . Math 70
1 . Math 76
1 . Physics 98
1 . Physics 70
1 . Physics 76
我调查了这个:Gather multiple sets of columns 和其他一些人,但大多数人半途而废。
我也试过这个问题的答案(我把收入栏改成预先以T_minus_*结尾):
我试过了
library(data.table)
res = melt(setDT(sample_df),
measure.vars = patterns("^Exam", "^Grade"),
variable.name = "i")
res[, i := factor(i, labels = c("3","2", "1"))]
它完成了我需要的大部分事情,但是,我需要我的 i 列中的值是整数而不是分类变量,因为我需要它们用于未来的计算。
我尝试这样做 res$i <- as.numeric(res$i)
,但是这改变了顺序,即“3”被计算为 1,“1”被计算为 3。
我试图将其排除在外,但这也为我提供了 1、2、3 以及 i 列值。
当我将收益列更改为 Earnings_T_minus_* 时,我能否以某种方式在 i 列中获取这些 * 值?
library(data.table)
res = melt(setDT(sample_df),
measure.vars = patterns("^Exam_T_minus_*", "^Grade_T_minus_*"),
variable.name = "i")
抱歉,这个问题变得有点长而且可能令人困惑,但希望有人能指引我正确的方向。
使用 dplyr
和 tidyr
的解决方案。
需要两次gather
过程。第一次,我们可以收集 i(as t_minus_i_)
和 Exam
。第二次,我们可以收集 Year
和 Grade
.
starts_with
是一个辅助函数,可以 select 以字符串开头的列。 sub
是将字符串替换为空字符串"",进一步格式化列。 as.integer
是将字符数转换为整数。 dt2
是最终输出。
library(dplyr)
library(tidyr)
dt2 <- dt %>%
# First gather process: gather the i(as t_minus_i_) and Exam
gather(`i(as t_minus_i_)`, Exam, starts_with("Exam")) %>%
mutate(`i(as t_minus_i_)` = as.integer(sub("Exam_t_minus_", "", `i(as t_minus_i_)`))) %>%
# Second gather process: gather the Grade
gather(Year, Grade, starts_with("Grade")) %>%
mutate(Year = as.integer(sub("Grade_", "", Year))) %>%
arrange(ID)
dt2
# ID i(as t_minus_i_) Exam Year Grade
# 1 1 3 Math 2012 98
# 2 1 2 Physics 2012 98
# 3 1 1 Chemestry 2012 98
# 4 1 3 Math 2013 70
# 5 1 2 Physics 2013 70
# 6 1 1 Chemestry 2013 70
# 7 1 3 Math 2014 76
# 8 1 2 Physics 2014 76
# 9 1 1 Chemestry 2014 76
# 10 2 3 English 2012 77
# 11 2 2 French 2012 77
# 12 2 1 Russian 2012 77
# 13 2 3 English 2013 85
# 14 2 2 French 2013 85
# 15 2 1 Russian 2013 85
# 16 2 3 English 2014 59
# 17 2 2 French 2014 59
# 18 2 1 Russian 2014 59
# 19 3 3 English 2012 65
# 20 3 2 Chemistry 2012 65
# 21 3 1 Biology 2012 65
# 22 3 3 English 2013 77
# 23 3 2 Chemistry 2013 77
# 24 3 1 Biology 2013 77
# 25 3 3 English 2014 69
# 26 3 2 Chemistry 2014 69
# 27 3 1 Biology 2014 69
数据
dt <- read.table(text = "ID Exam_t_minus_3 Exam_t_minus_2 Exam_t_minus_1 Grade_2012 Grade_2013 Grade_2014
1 Math Physics Chemestry 98 70 76
2 English French Russian 77 85 59
3 English Chemistry Biology 65 77 69",
header = TRUE, stringsAsFactors = FALSE)
您的 data.table
方法几乎是正确的。使用多列重塑是可行的方法。
library(data.table)
melt(setDT(sample_df),
measure.vars = patterns("^Exam", "^Grade"), value.name = c("Exam", "Grade"),
variable.name = "i", variable.factor = FALSE)[
, i := 4L - as.integer(i)][order(ID)]
ID i Exam Grade 1: 1 3 Math 98 2: 1 2 Physics 70 3: 1 1 Chemistry 76 4: 2 3 English 77 5: 2 2 French 85 6: 2 1 Russian 59 7: 3 3 English 65 8: 3 2 Chemistry 77 9: 3 1 Biology 69
唯一的修改是将 variable.factor = FALSE
作为参数传递给 melt()
,在强制转换为整数后对 i
进行一些算术运算,并适当地 order()
结果。