R语言进阶——数据整形
当前位置:以往代写 > 其他教程 >R语言进阶——数据整形
2019-06-14

R语言进阶——数据整形

R语言进阶——数据整形

 一、通过从头构建数据举办整形

数据整形最直接的思路就把数据全部向量化,然后按要求用向量构建其他范例的数据。这样是不是会发生大量的中间变量、占用大量内存?没错。R语言的任何函数(包罗赋值)操纵城市有同样的问题,因为R函数的参数通报方法是传值不传址,变量不行能原地点修改后再放回原地点。

矩阵和多维数组的向量化有直接的范例转换函数: as.vector,向量化后的功效顺序是先列后行再其他:

  1. > (x <- matrix(1:4, ncol=2))  #为节减空间,下面的功效省略了一些空行 
  2.      [,1] [,2] 
  3. [1,]    1    3 
  4. [2,]    2    4 
  5. > as.vector(x) 
  6. [1] 1 2 3 4 
  7. > (x <- array(1:8, dim=c(2,2,2))) 
  8. , , 1 
  9.      [,1] [,2] 
  10. [1,]    1    3 
  11. [2,]    2    4 
  12. , , 2 
  13.      [,1] [,2] 
  14. [1,]    5    7 
  15. [2,]    6    8 
  16. > as.vector(x) 
  17. [1] 1 2 3 4 5 6 7 8 

列表向量化可以用unlist,数据框本质是元素长度沟通的列表,所以也用unlist:

  1. > (x <- list(x=1:3, y=5:10)) 
  2. $x 
  3. [1] 1 2 3 
  4. $y 
  5.  
  6. [1]  5  6  7  8  9 10 
  7. > unlist(x) 
  8. x1 x2 x3 y1 y2 y3 y4 y5 y6  
  9.  1  2  3  5  6  7  8  9 10  
  10. > x <- data.frame(x=1:3, y=5:7) 
  11. > unlist(x) 
  12. x1 x2 x3 y1 y2 y3  
  13.  1  2  3  5  6  7 

其他范例的数据一般都可以通过数组、矩阵或列表转成向量。一些软件包有自界说的数据范例,假如思量周到的话应该会有符合的范例转换函数。

 

二、transform 和 within函数

transform
函数对数据框举办操纵,浸染是为原数据框增加新的列变量。但应该留意的是“原数据框”基础不是本来的谁人数据框,而是一个它的拷贝。下面代码为
airquality数据框增加了一列log.ozone,但因为没有把功效赋值给原变量名,所以原数据是稳定的:

  1. > head(airquality,2) 
  2.   Ozone Solar.R Wind Temp Month Day 
  3. 1    41     190  7.4   67     5   1 
  4. 2    36     118  8.0   72     5   2 
  5. > aq <- transform(airquality, loglog.ozone=log(Ozone)) 
  6. > head(airquality,2) 
  7.   Ozone Solar.R Wind Temp Month Day 
  8. 1    41     190  7.4   67     5   1 
  9. 2    36     118  8.0   72     5   2 
  10. > head(aq,2) 
  11.   Ozone Solar.R Wind Temp Month Day log.ozone 
  12. 1    41     190  7.4   67     5   1  3.713572 
  13. 2    36     118  8.0   72     5   2  3.583519 

transform可以增加新列变量,可以改变列变量的值,也可以通过NULL赋值的方法删除列变量:

  1. > aq <- transform(airquality, loglog.ozone=log(Ozone), Ozone=NULL, WindWind=Wind^2) 
  2. > head(aq,2) 
  3.   Solar.R  Wind Temp Month Day log.ozone 
  4. 1     190 54.76   67     5   1  3.713572 
  5. 2     118 64.00   72     5   2  3.583519 
  6.  
  7. > aq <- transform(airquality, loglog.ozone=log(Ozone), Ozone=NULL, Month=NULL, WindWind=Wind^2) 
  8. > head(aq,2) 
  9.   Solar.R  Wind Temp Day log.ozone 
  10. 1     190 54.76   67   1  3.713572 
  11. 2     118 64.00   72   2  3.583519 

#p#分页标题#e#

within 比 transform 机动些,除数据框外还可以利用其他范例数据,但用法不大一样,并且函数好像也不足完善:

  1. > aq <- within(airquality, { 
  2. + log.ozone <- log(Ozone) 
  3. + squared.wind <- Wind^2 
  4. + rm(Ozone, Wind) 
  5. + } ) 
  6. > head(aq,2) 
  7.   Solar.R Temp Month Day squared.wind log.ozone 
  8. 1     190   67     5   1        54.76  3.713572 
  9. 2     118   72     5   2        64.00  3.583519 
  10.  
  11. > (x <- list(a=1:3, b=letters[3:10], c=LETTERS[9:14])) 
  12. $a 
  13. [1] 1 2 3 
  14. $b 
  15. [1] "c" "d" "e" "f" "g" "h" "i" "j" 
  16. $c 
  17. [1] "I" "J" "K" "L" "M" "N" 
  18.  
  19. > within(x, {log.a <- log(a); d <- paste(b, c, sep=':'); rm(b)}) 
  20. $a 
  21. [1] 1 2 3 
  22. $c 
  23. [1] "I" "J" "K" "L" "M" "N" 
  24. $d 
  25. [1] "c:I" "d:J" "e:K" "f:L" "g:M" "h:N" "i:I" "j:J" 
  26. $log.a 
  27. [1] 0.0000000 0.6931472 1.0986123 
  28. > within(x, {log.a <- log(a); d <- paste(b, c, sep=':'); rm(b,c)}) 
  29. $a 
  30. [1] 1 2 3 
  31. $b   #为什么删除两个列表元素会获得这样的功效? 
  32.  
  33. NULL 
  34. $c 
  35. NULL 
  36. $d 
  37. [1] "c:I" "d:J" "e:K" "f:L" "g:M" "h:N" "i:I" "j:J" 
  38. $log.a 
  39. [1] 0.0000000 0.6931472 1.0986123 

 

三、reshape、stack和unstack 函数

reshape是R base/stats的函数,主要用于数据框长名目和宽名目之间的转换。reshape函数的参数许多,不容易记,牛人Hadley Wickham搞出reshape和reshape2包今后这个函数险些被人遗忘:

  1. reshape(data, varying = NULL, v.names = NULL, timevar = "time", 
  2.         idvar = "id", ids = 1:NROW(data), 
  3.         times = seq_along(varying[[1]]), 
  4.         drop = NULL, direction, new.row.names = NULL, 
  5.         sep = ".", 
  6.         split = if (sep == "") { 
  7.             list(regexp = "[A-Za-z][0-9]", include = TRUE) 
  8.         } else { 
  9.             list(regexp = sep, include = FALSE, fixed = TRUE)} 
  10.         ) 

既然可以被遗忘,那就等你走投无路的时候(预计不会有这样的环境产生)再去相识它吧。

#p#分页标题#e#

stack 和 unstack 的浸染和reshape雷同,用于数据框/列表的长、宽名目之间转换。数据框宽名目是我们记录原始数据常用的名目,雷同这样:

  1. > x <- data.frame(CK=c(1.1, 1.2, 1.1, 1.5), T1=c(2.1, 2.2, 2.3, 2.1), T2=c(2.5, 2.2, 2.3, 2.1)) 
  2. > x 
  3.    CK  T1  T2 
  4. 1 1.1 2.1 2.5 
  5. 2 1.2 2.2 2.2 
  6. 3 1.1 2.3 2.3 
  7. 4 1.5 2.1 2.1 

一般统计和作图用的是长名目,stack可以做这个:

  1. > (xx <- stack(x)) 
  2.    values ind 
  3. 1     1.1  CK 
  4. 2     1.2  CK 
  5. 3     1.1  CK 
  6. 4     1.5  CK 
  7. 5     2.1  T1 
  8. 6     2.2  T1 
  9. 7     2.3  T1 
  10. 8     2.1  T1 
  11. 9     2.5  T2 
  12. 10    2.2  T2 
  13. 11    2.3  T2 
  14. 12    2.1  T2 

而unstack的浸染正好和stack相反,可是要留意它的第二个参数是公式范例:公式左边的变量是值,右边的变量会被当成因子范例,它的每个程度城市形成一列:

  1. > unstack(xx, values~ind) 
  2.    CK  T1  T2 
  3. 1 1.1 2.1 2.5 
  4. 2 1.2 2.2 2.2 
  5. 3 1.1 2.3 2.3 
  6. 4 1.5 2.1 2.1 

 

四、reshape/reshape2 包

Hadley Wickham,牛人,很牛X的一小我私家,写了许多R语言包,著名的有ggplot2, plyr,
reshape/reshape2等。reshape2包是reshape包的重写版,用reshape2就行,都在CRAN源中,用
install.packages函数就可以安装。reshape/reshape2的函数很少,一般用户直接利用的是melt, acast 和
dcast 函数。

melt是溶解/解析的意思,即拆分数据。reshape/reshape2的melt函数是个S3通用函数,它会按照数据范例(数据框,数组或列表)选择melt.data.frame, melt.array 或 melt.list函数举办实际操纵。

假如是数组(array)范例,melt的用法就很简朴,它依次对各维度的名称举办组合将数据举办线性/向量化。假如数组有n维,那么获得的功效共有n+1列,前n列记录数组的位置信息,最后一列才是视察值:

  1. > datax <- array(1:8, dim=c(2,2,2)) 
  2. > melt(datax) 
  3.   Var1 Var2 Var3 value 
  4. 1    1    1    1     1 
  5. 2    2    1    1     2 
  6. 3    1    2    1     3 
  7. 4    2    2    1     4 
  8. 5    1    1    2     5 
  9. 6    2    1    2     6 
  10. 7    1    2    2     7 
  11. 8    2    2    2     8 
  12.  
  13. > melt(datax, varnames=LETTERS[24:26],value.name="Val") 
  14.   X Y Z Val 
  15. 1 1 1 1   1 
  16. 2 2 1 1   2 
  17. 3 1 2 1   3 
  18. 4 2 2 1   4 
  19. 5 1 1 2   5 
  20. 6 2 1 2   6 
  21. 7 1 2 2   7 
  22. 8 2 2 2   8 

#p#分页标题#e#

假如是列表数据,melt 函数将列表中的数据拉成两列,一列记录列表元素的值,另一列记录列表元素的名称;假如列表中的元素是列表,则增加列变量存储元素名称。元素值分列在前,名称在后,越是较高级的列表元素名称越靠后:

  1. > datax <- list(agi="AT1G10000", GO=c("GO:1010","GO:2020"), KEGG=c("0100", "0200", "0300")) 
  2. > melt(datax) 
  3.       value   L1 
  4. 1 AT1G10000  agi 
  5. 2   GO:1010   GO 
  6. 3   GO:2020   GO 
  7. 4      0100 KEGG 
  8. 5      0200 KEGG 
  9. 6      0300 KEGG 
  10. > melt(list(at_0100=datax)) 
  11.       value   L2      L1 
  12. 1 AT1G10000  agi at_0100 
  13. 2   GO:1010   GO at_0100 
  14. 3   GO:2020   GO at_0100 
  15. 4      0100 KEGG at_0100 
  16. 5      0200 KEGG at_0100 
  17. 6      0300 KEGG at_0100 

假如数据是数据框范例,melt的参数就稍微巨大些:

  1. melt(data, id.vars, measure.vars, 
  2.     variable.name = "variable", ..., na.rm = FALSE, 
  3.     value.name = "value") 

个中 id.vars 是被当做维度的列变量,每个变量在功效中占一列;measure.vars
是被当成视察值的列变量,它们的列变量名称和值别离构成 variable 和 value两列,列变量名称用variable.name 和
value.name来指定。我们用airquality数据来看看:

  1. > str(airquality) 
  2. 'data.frame':   153 obs. of  6 variables: 
  3.  $ Ozone  : int  41 36 12 18 NA 28 23 19 8 NA ... 
  4.  $ Solar.R: int  190 118 149 313 NA NA 299 99 19 194 ... 
  5.  $ Wind   : num  7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ... 
  6.  $ Temp   : int  67 72 74 62 56 66 65 59 61 69 ... 
  7.  $ Month  : int  5 5 5 5 5 5 5 5 5 5 ... 
  8.  $ Day    : int  1 2 3 4 5 6 7 8 9 10 ... 

假如规划按月份阐明臭氧和太阳辐射、风速、温度三者(列2:4)的干系,我们把它转生长名目数据框:

  1. > aq <- melt(airquality, var.ids=c("Ozone", "Month", "Day"),  
  2. + measure.vars=c(2:4), variable.name="V.type", value.name="value") 
  3. > str(aq) 
  4. 'data.frame':   459 obs. of  5 variables: 
  5.  $ Ozone : int  41 36 12 18 NA 28 23 19 8 NA ... 
  6.  $ Month : int  5 5 5 5 5 5 5 5 5 5 ... 
  7.  $ Day   : int  1 2 3 4 5 6 7 8 9 10 ... 
  8.  $ V.type: Factor w/ 3 levels "Solar.R","Wind",..: 1 1 1 1 1 1 1 1 1 1 ... 
  9.  $ value : num  190 118 149 313 NA NA 299 99 19 194 ... 

#p#分页标题#e#

var.ids 可以写成id,measure.vars可以写成measure。id(即var.ids)和
视察值(即measure.vars)这两个参数可以只指定个中一个,剩余的列被当成别的一个参数的值;假如两个都省略,数值型的列被当作视察值,其他的
被当成id。假如想省略参数可能去掉部门数据,参数名较好用 id/measure,不然获得的功效很大概不是你要的:

  1. > str(melt(airquality, var.ids=c(1,5,6), measure.vars=c(2:4))) 
  2. 'data.frame':   459 obs. of  5 variables: 
  3.  $ Ozone   : int  41 36 12 18 NA 28 23 19 8 NA ... 
  4.  $ Month   : int  5 5 5 5 5 5 5 5 5 5 ... 
  5.  $ Day     : int  1 2 3 4 5 6 7 8 9 10 ... 
  6.  $ variable: Factor w/ 3 levels "Solar.R","Wind",..: 1 1 1 1 1 1 1 1 1 1 ... 
  7.  $ value   : num  190 118 149 313 NA NA 299 99 19 194 ... 
  8. > str(melt(airquality, var.ids=1, measure.vars=c(2:4)))   #看这里,固然id只引用了一列,但功效却不是这样 
  9. 'data.frame':   459 obs. of  5 variables: 
  10.  $ Ozone   : int  41 36 12 18 NA 28 23 19 8 NA ... 
  11.  $ Month   : int  5 5 5 5 5 5 5 5 5 5 ... 
  12.  $ Day     : int  1 2 3 4 5 6 7 8 9 10 ... 
  13.  $ variable: Factor w/ 3 levels "Solar.R","Wind",..: 1 1 1 1 1 1 1 1 1 1 ... 
  14.  $ value   : num  190 118 149 313 NA NA 299 99 19 194 ... 
  15. > str(melt(airquality, var.ids=1))  #这样用更惨,功效不是我们要的吧? 
  16.  
  17. Using  as id variables 
  18. 'data.frame':   918 obs. of  2 variables: 
  19.  $ variable: Factor w/ 6 levels "Ozone","Solar.R",..: 1 1 1 1 1 1 1 1 1 1 ... 
  20.  $ value   : num  41 36 12 18 NA 28 23 19 8 NA ... 
  21. > str(melt(airquality, id=1))  #这样才行 
  22. 'data.frame':   765 obs. of  3 variables: 
  23.  $ Ozone   : int  41 36 12 18 NA 28 23 19 8 NA ... 
  24.  $ variable: Factor w/ 5 levels "Solar.R","Wind",..: 1 1 1 1 1 1 1 1 1 1 ... 
  25.  $ value   : num  190 118 149 313 NA NA 299 99 19 194 ... 

数据整容有什么用?虽然有。别忘了reshape2和ggplot2都是Hadley Wickham的作品,melt 今后的数据(称为molten数据)用ggplot2做统计图就很利便了,可以快速做出我们需要的图形:

  1. library(ggplot2) 
  2.  
  3. aq$Month <- factor(aq$Month) 
  4. p <- ggplot(data=aq, aes(x=Ozone, y=value, color=Month)) + theme_bw() 
  5. p + geom_point(shape=20, size=4) + geom_smooth(aes(group=1), fill="gray80") + facet_wrap(~V.type, scales="free_y") 

R语言进阶——数据整形

  • > head(dcast(aq, Ozone+Month+Day~V.type)) 
  •   Ozone Month Day Solar.R Wind Temp 
  • 1     1     5  21       8  9.7   59 
  • 2     4     5  23      25  9.7   61 
  • 3     6     5  18      78 18.4   57 
  • 4     7     5  11      NA  6.9   74 
  • 5     7     7  15      48 14.3   80 
  • 6     7     9  24      49 10.3   69 
  • #p#分页标题#e#

    cast函数的浸染不可是还原数据,还可以利用函数对数据举办汇总(aggregate)。事实上,melt函数是为cast处事的,目标是利用cast函数对数据举办aggregate:

    1. > dcast(aq, Month~V.type, fun.aggregate=mean, na.rm=TRUE) 
    2.   Month  Solar.R      Wind     Temp 
    3. 1     5 181.2963 11.622581 65.54839 
    4. 2     6 190.1667 10.266667 79.10000 
    5. 3     7 216.4839  8.941935 83.90323 
    6. 4     8 171.8571  8.793548 83.96774 
    7. 5     9 167.4333 10.180000 76.90000 

     

    五、plyr 包

    plyr
    的成果已经远远超出数据整容的范畴,Hadley在plyr中应用了split-apply-combine的数据处理惩罚哲学,即:先将数据疏散,然后应用
    某些处理惩罚函数,最后将功效从头组合成所需的形式返回。某些人士喜欢用“揉”来表述这样的数据处理惩罚;“揉”,把数据对面团捣来捣去,很哲,砖家们的砖头落下
    来,拍死人毫不偿命R语言进阶——数据整形

  • > library(ath1121501.db) 
  • > keggs <- as.list(ath1121501PATH[mappedkeys(ath1121501PATH)]) 
  • > head(ldply(keggs, paste, collapse='; ')) 
  •         .id                                              V1 
  • 1 261579_at                                           00190 
  • 2 261569_at                                           04712 
  • 3 261583_at 00010; 00020; 00290; 00620; 00650; 01100; 01110 
  • 4 261574_at                      00903; 00945; 01100; 01110 
  • 5 261043_at                             00051; 00520; 01100 
  • 6 261044_at                                           04122 
  • plyr包的函数较多,不再一一先容,更多用法请参考它的在线辅佐,Hadley 也写了很具体的tutorial:http://plyr.had.co.nz/09-user/

     

     

    #p#分页标题#e#

     

     

    本文原标题:R语言进阶之4:数据整形(reshape)

    本文转载自:http://helloxxxxxx.blog.163.com/blog/static/21601509520133343821837/?latestBlog

      关键字:

    在线提交作业