Re: [问题] reshape 资料转换

楼主: celestialgod (天)   2016-03-07 17:10:34
※ 引述《criky (立业成家)》之铭言:
: [问题类型]:
:
: 程式咨询(我想用R 做某件事情,但是我不知道要怎么用R 写出来)
: [软件熟悉度]:
: 新手(没写过程式,R 是我的第一次)
: [问题叙述]:
: 我的资料像是学校的成绩系统
: 字段有学生id,学年,学期,科目id,科目名,成绩
: 一个学生有n列,
: 现在想将一个学生拉成一列
: 我是先paste(学年+学期),再用reshape函数作,
: data.2<-reshape(data.1,v.names="成绩",idvar="学号",timevar="学年学期
: ",direction="wide")
: 但转换后成绩的部分,
: 只有某个科目的成绩,
: 若用先paste(学年+学期+科目id),再用reshape函数作,
: 是可以作出来,不过这样NA值会很多,
: 我想要用"每个学生的学期平均数"作整理
: 所以资料字段会是1个学生id+8个学期平均:
: 学生id 第1学年第1学期平均 第1学年第2学期平均 第2学年第1学期平均
: …
: 不知道要怎么写,
: 请问一下,谢谢。
: [环境叙述]:
: win8
: [关键字]:
: reshape
library(data.table)
library(dplyr)
library(magrittr)
# data generation
# 假设一百个学生,五科,三年,上下两学期
numStu <- 100
numSubject <- 5
numYear <- 3
numSemester <- 2
datBigTable <- data.table(stuID = rep(1:numStu, each = numSubject*numYear*
numSemester), year = rep(102:(101+numYear), times = numStu*numSubject,
each = numSemester),
semester = rep(1:numSemester, times = numStu*numSubject*numYear),
subjectID = rep(1:numSubject, times = numStu, each = numSemester*numYear))
datBigTable %<>% mutate(Grade = sample(1:100, nrow(.), TRUE),
subjectName = c("国文", "英文", "数学", "自然", "社会")[subjectID]) %>%
tbl_dt(FALSE)
# Source: local data table [3,000 x 6]
#
# stuID year semester subjectID Grade subjectName
# (int) (int) (int) (int) (int) (chr)
# 1 1 102 1 1 32 国文
# 2 1 102 2 1 95 国文
# 3 1 103 1 1 95 国文
# 4 1 103 2 1 7 国文
# 5 1 104 1 1 60 国文
# 6 1 104 2 1 65 国文
# 7 1 102 1 2 85 英文
# 8 1 102 2 2 28 英文
# 9 1 103 1 2 33 英文
# 10 1 103 2 2 7 英文
# .. ... ... ... ... ... ...
datBigTable %>% mutate(yearSemester = sprintf("%03i%02i", year, semester)) %>%
group_by(stuID, yearSemester) %>% summarise(meanGrade = mean(Grade)) %>%
dcast.data.table(stuID ~ yearSemester, value.var = "meanGrade") %>%
tbl_dt(FALSE)
# Source: local data table [100 x 7]
#
# stuID 10201 10202 10301 10302 10401 10402
# (int) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
# 1 1 47.4 55.0 36.2 12.8 60.4 36.8
# 2 2 59.2 58.2 58.0 36.4 57.2 47.8
# 3 3 53.8 59.2 60.8 54.2 65.4 34.0
# 4 4 70.0 69.4 66.2 42.2 48.8 45.0
# 5 5 52.8 64.8 34.2 39.4 59.4 50.0
# 6 6 50.0 50.2 45.2 60.6 59.0 68.6
# 7 7 38.0 46.6 50.0 49.6 32.2 52.2
# 8 8 53.4 58.6 47.0 37.6 56.8 47.8
# 9 9 26.6 64.0 37.6 25.2 65.4 55.2
# 10 10 47.0 40.2 26.4 45.6 65.6 40.0
# .. ... ... ... ... ... ... ...
原本想用tidyr:::spread,不过不知道怎么了,dplyr更新到0.4.3就不给我用了Orz
更新,突然想到我转换后的变量名称是数字,所以才会不行....
library(tidyr)
datBigTable %<>% mutate(year = year - 101)
datBigTable %>% mutate(yearSemester = sprintf("第%i学年第%i学期平均",
year, semester)) %>% group_by(stuID, yearSemester) %>%
summarise(meanGrade = mean(Grade)) %>%
spread(yearSemester, meanGrade) %>% tbl_dt(FALSE)
# Source: local data table [100 x 7]
#
# stuID 第1学年第1学期平均 第1学年第2学期平均 第2学年第1学期平均
# (int) (dbl) (dbl) (dbl)
# 1 1 54.6 51.4 41.4
# 2 2 57.6 49.4 63.6
# 3 3 46.8 62.2 51.4
# 4 4 45.0 62.8 60.0
# 5 5 43.8 49.6 43.8
# 6 6 54.4 44.0 59.2
# 7 7 47.6 65.4 52.0
# 8 8 63.6 68.2 75.2
# 9 9 40.4 41.6 50.0
# 10 10 39.0 52.4 50.2
# .. ... ... ... ...
#
# 第2学年第2学期平均 第3学年第1学期平均 第3学年第2学期平均
# ... ... ...
作者: criky (2501-2)   2016-03-07 22:22:00
板主签名档的文章套件几乎可以整理大部分的资料啊~厉害!谢谢!我先试试有问题再请教我执行后有出现错误讯息如下:Error in dcast.data.table(., stuID ~ yearSemester,value.var = "meanGrade") :'data' must be a data.table.不知道还需要修改什么?

Links booklink

Contact Us: admin [ a t ] ucptt.com