用户工具

侧边栏

站点工具

本站推荐

最多访问

本页目录

您的足迹: • class • statistics • reshape

Reshape包的melt和cast函数介绍

我现在已经不教用这个包了,因为R核心包stats的reshape函数足够方便,还更灵活。用R核心的包还有一个好处就是不会什么时候没有人维护就不兼容了。 这是之前教程里的内容,这里单独放一个页面,留个纪念吧。

reshape包里我主要用的是cast和melt两个函数,如果没有安装reshape这个包,则预先安装一下。

options(stringsAsFactors=FALSE)
options(scipen=20) # 发现学号显示为科学计数法了,可以通过这个设置来改变。
library(reshape)
 
dat <- read.delim("ftp://ftp.biolab.wang/data/成绩.tsv", header=TRUE, sep='\t', encoding="GBK")
str(dat)
##  'data.frame':   830 obs. of  7 variables:
##   $ 学号    : num  71024000001 71024000001 71024000001 71024000001 71024000002 ...
##   $ 姓名    : chr  "梁全" "梁全" "梁全" "梁全" ...
##   $ 班级    : chr  "3班" "3班" "3班" "3班" ...
##   $ 课程编号: int  1006001 1006017 1006036 1006002 1006001 1006017 1006036 1006002 1006001 1006017 ...
##   $ 课程名称: chr  "体育" "解剖学" "物理学" "英语" ...
##   $ 学分    : num  2 4.5 4 4 2 4.5 4 4 2 4.5 ...
##   $ 成绩    : int  76 81 61 61 77 83 75 67 80 72 ...
 
head(dat)
##           学号   姓名 班级 课程编号 课程名称 学分 成绩
##  1 71024000001   梁全  3班  1006001     体育  2.0   76
##  2 71024000001   梁全  3班  1006017   解剖学  4.5   81
##  3 71024000001   梁全  3班  1006036   物理学  4.0   61
##  4 71024000001   梁全  3班  1006002     英语  4.0   61
##  5 71024000002 李海丽  3班  1006001     体育  2.0   77
##  6 71024000002 李海丽  3班  1006017   解剖学  4.5   83

我们可以把每个人的所有成绩放一行展示,使用cast函数,将长数据转换为宽数据:

Dat <- cast(dat, 学号+姓名+班级~课程名称, value="成绩")
##  Aggregation requires fun.aggregate: length used as default
 
head(Dat)
##           学号   姓名 班级 基础化学 解剖学 体育 物理学 细胞生物学 英语
##  1 71024000001   梁全  3班        0      1    1      1          0    1
##  2 71024000002 李海丽  3班        0      1    1      1          0    1
##  3 71024000003 李昕婧  3班        0      1    1      1          0    1
##  4 71024000004   廖娇  3班        0      1    1      1          0    1
##  5 71024000005 陈雅文  3班        0      1    1      1          0    1
##  6 71024000006 李清玲  3班        0      1    1      1          0    1
 
Dat <- cast(dat, 学号+姓名+班级~课程名称, value="成绩", fun.aggregate=max, fill=NA)
 
head(Dat)
##           学号   姓名 班级 基础化学 解剖学 体育 物理学 细胞生物学 英语
##  1 71024000001   梁全  3班       NA     81   76     61         NA   61
##  2 71024000002 李海丽  3班       NA     83   77     75         NA   67
##  3 71024000003 李昕婧  3班       NA     72   80     68         NA   81
##  4 71024000004   廖娇  3班       NA     80   82     78         NA   83
##  5 71024000005 陈雅文  3班       NA     77   79     73         NA   76
##  6 71024000006 李清玲  3班       NA     81   86     81         NA   70
 
str(Dat)
##  List of 9
##   $ 学号      : num [1:161] 71024000001 71024000002 71024000003 71024000004 71024000005 ...
##   $ 姓名      : chr [1:161] "梁全" "李海丽" "李昕婧" "廖娇" ...
##   $ 班级      : chr [1:161] "3班" "3班" "3班" "3班" ...
##   $ 基础化学  : int [1:161] NA NA NA NA NA NA NA NA NA NA ...
##   $ 解剖学    : int [1:161] 81 83 72 80 77 81 68 81 84 82 ...
##   $ 体育      : int [1:161] 76 77 80 82 79 86 84 82 84 87 ...
##   $ 物理学    : int [1:161] 61 75 68 78 73 81 68 79 79 76 ...
##   $ 细胞生物学: int [1:161] NA NA NA NA NA NA NA NA NA NA ...
##   $ 英语      : int [1:161] 61 67 81 83 76 70 81 70 83 83 ...
##   - attr(*, "row.names")= int [1:161] 1 2 3 4 5 6 7 8 9 10 ...
##   - attr(*, "idvars")= chr [1:3] "学号" "姓名" "班级"
##   - attr(*, "rdimnames")=List of 2
##    ..$ :'data.frame':    161 obs. of  3 variables:
##    .. ..$ 学号: num [1:161] 71024000001 71024000002 71024000003 71024000004 71024000005 ...
##    .. ..$ 姓名: chr [1:161] "梁全" "李海丽" "李昕婧" "廖娇" ...
##    .. ..$ 班级: chr [1:161] "3班" "3班" "3班" "3班" ...
##    ..$ :'data.frame':    6 obs. of  1 variable:
##    .. ..$ 课程名称: chr [1:6] "基础化学" "解剖学" "体育" "物理学" ...
 
class(Dat)
##  [1] "cast_df"    "data.frame"
 
Dat <- data.frame(Dat)
str(Dat)
##  'data.frame':   161 obs. of  9 variables:
##   $ 学号      : num  71024000001 71024000002 71024000003 71024000004 71024000005 ...
##   $ 姓名      : chr  "梁全" "李海丽" "李昕婧" "廖娇" ...
##   $ 班级      : chr  "3班" "3班" "3班" "3班" ...
##   $ 基础化学  : int  NA NA NA NA NA NA NA NA NA NA ...
##   $ 解剖学    : int  81 83 72 80 77 81 68 81 84 82 ...
##   $ 体育      : int  76 77 80 82 79 86 84 82 84 87 ...
##   $ 物理学    : int  61 75 68 78 73 81 68 79 79 76 ...
##   $ 细胞生物学: int  NA NA NA NA NA NA NA NA NA NA ...
##   $ 英语      : int  61 67 81 83 76 70 81 70 83 83 ...

可看到这里返回了一个信息,有的同学成绩对应多个值,这时候就需要指定汇总(Aggregation)函数,比如这里使用max,最最大值也就是最高分。可以看到,cast得到的对象并不是一个单纯的data.frame, 还是cast_df, 可以将它转化为data.frame。 设置了options(scipen=20),如果发现学号显示为科学计数法了,可以通过这个设置来改变。

met则是cast的逆向过程,将宽数据变形为长数据

DAT <- melt(Dat, id=1:3)
 
str(DAT)
##  'data.frame':   966 obs. of  5 variables:
##   $ 学号    : num  71024000001 71024000002 71024000003 71024000004 71024000005 ...
##   $ 姓名    : chr  "梁全" "李海丽" "李昕婧" "廖娇" ...
##   $ 班级    : chr  "3班" "3班" "3班" "3班" ...
##   $ variable: Factor w/ 6 levels "基础化学","解剖学",..: 1 1 1 1 1 1 1 1 1 1 ...
##   $ value   : int  NA NA NA NA NA NA NA NA NA NA ...
 
names(DAT)[4:5] <- c("科目", "成绩")
 
str(melt(Dat))
##  Using 姓名, 班级 as id variables
##  'data.frame':   1127 obs. of  4 variables:
##   $ 姓名    : chr  "梁全" "李海丽" "李昕婧" "廖娇" ...
##   $ 班级    : chr  "3班" "3班" "3班" "3班" ...
##   $ variable: Factor w/ 7 levels "学号","基础化学",..: 1 1 1 1 1 1 1 1 1 1 ...
##   $ value   : num  71024000001 71024000002 71024000003 71024000004 71024000005 ...

melt之后变量一列的表头默认为variable,而数值一列默认为value,可以把列名改成所需要的。如果不设置id列,那么R会去把字符型的列当作id,这种行为是我们无法控制的,因此,设置好id是非常重要的。也可以通过id.vars和measure.vars来更具体地指定。

另外Reshape的作者Hadley Wickham还有一个包叫reshape2,Reshape2现在已经退休了。在某些方面比Reshape高效,但在我们一般的使用中用Reshape就足够了。


本网页已被访问162次。


页面工具

Powered by DokuWiki | ©2018-8102 Hong Wang | 桂ICP备18010616号 | 桂公网安备 45010302002017号