※ 引述《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學期平均
# ... ... ...