R语言-数据整形之简介

R语言中数据整形

前言

  从不同途径得到的数据的组织方式是多种多样的,很多数据都要经过整理才能进行有效的分析,数据整形不仅仅是为了改善数据的外观,也是进行一些统计分析和作图前必要的步骤。数据整形和数据凝练/汇总往往密不可分,这是门学问,是R语言数据处理的内容之一。

目录

 1. 通过重新构建数据进行整形

 2. transform 和 within 函数

 3. stack 和 unstack 函数

1. 通过重新构建数据进行整形

  数据整形最直接的思路就把数据全部向量化,然后按要求用向量构建其他类型的数据。这样是不是会产生大量的中间变量、占用大量内存?没错。R语言的任何函数(包括赋值)操作都会有同样的问题,因为R函数的参数传递方式是传值不传址,变量不可能原地址修改后再放回原地址。

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

	> (x <- matrix(1:4, ncol=2))  #为节省空间,下面的结果省略了一些空行 
	     [,1] [,2] 
	[1,]    1    3 
	[2,]    2    4 
	> as.vector(x) 
	[1] 1 2 3 4 
	> (x <- array(1:8, dim=c(2,2,2))) 
	, , 1 
	     [,1] [,2] 
	[1,]    1    3 
	[2,]    2    4 
	, , 2 
	     [,1] [,2] 
	[1,]    5    7 
	[2,]    6    8 
	> as.vector(x) 
	[1] 1 2 3 4 5 6 7 8 

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

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

  其他类型的数据一般都可以通过数组、矩阵或列表转成向量。一些软件包有自定义的数据类型,如果考虑周到的话应该会有合适的类型转换函数。

2. transform 和 within 函数

  transform 函数对数据框进行操作,作用是为原数据框增加新的列变量。但应该注意的是“原数据框”根本不是原来的那个数据框,而是一个它的拷贝。下面代码为airquality数据框增加了一列log.ozone,但因为没有把结果赋值给原变量名,所以原数据是不变的:

	> head(airquality,2) 
	  Ozone Solar.R Wind Temp Month Day 
	1    41     190  7.4   67     5   1 
	2    36     118  8.0   72     5   2 
	> aq <- transform(airquality, log.ozone=log(Ozone)) 
	> head(airquality,2) 
	  Ozone Solar.R Wind Temp Month Day 
	1    41     190  7.4   67     5   1 
	2    36     118  8.0   72     5   2 
	> head(aq,2) 
	  Ozone Solar.R Wind Temp Month Day log.ozone 
	1    41     190  7.4   67     5   1  3.713572 
	2    36     118  8.0   72     5   2  3.583519 

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

	> aq <- transform(airquality, log.ozone=log(Ozone), Ozone=NULL, Wind=Wind^2) 
	> head(aq,2) 
	  Solar.R  Wind Temp Month Day log.ozone 
	1     190 54.76   67     5   1  3.713572 
	2     118 64.00   72     5   2  3.583519 
	 
	> aq <- transform(airquality, log.ozone=log(Ozone), Ozone=NULL, Month=NULL, Wind=Wind^2) 
	> head(aq,2) 
	  Solar.R  Wind Temp Day log.ozone 
	1     190 54.76   67   1  3.713572 
	2     118 64.00   72   2  3.583519

  within 比 transform 灵活些,除数据框外还可以使用其他类型数据,但用法不大一样,而且函数似乎也不够完善:

	> aq <- within(airquality, { 
	+ log.ozone <- log(Ozone) 
	+ squared.wind <- Wind^2 
	+ rm(Ozone, Wind) 
	+ } ) 
	> head(aq,2) 
	  Solar.R Temp Month Day squared.wind log.ozone 
	1     190   67     5   1        54.76  3.713572 
	2     118   72     5   2        64.00  3.583519 
	 
	> (x <- list(a=1:3, b=letters[3:10], c=LETTERS[9:14])) 
	$a 
	[1] 1 2 3 
	$b 
	[1] "c" "d" "e" "f" "g" "h" "i" "j" 
	$c 
	[1] "I" "J" "K" "L" "M" "N" 
	 
	> within(x, {log.a <- log(a); d <- paste(b, c, sep=':'); rm(b)}) 
	$a 
	[1] 1 2 3 
	$c 
	[1] "I" "J" "K" "L" "M" "N" 
	$d 
	[1] "c:I" "d:J" "e:K" "f:L" "g:M" "h:N" "i:I" "j:J" 
	$log.a 
	[1] 0.0000000 0.6931472 1.0986123 
	> within(x, {log.a <- log(a); d <- paste(b, c, sep=':'); rm(b,c)}) 
	$a 
	[1] 1 2 3 
	$b   #为什么删除两个列表元素会得到这样的结果? 
	 
	NULL 
	$c 
	NULL 
	$d 
	[1] "c:I" "d:J" "e:K" "f:L" "g:M" "h:N" "i:I" "j:J" 
	$log.a 
	[1] 0.0000000 0.6931472 1.0986123 

3. stack 和 unstack 函数

  stack 和 unstack 的作用和reshape类似,用于数据框/列表的长、宽格式之间转换。数据框宽格式是我们记录原始数据常用的格式,类似这样:

	> 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)) 
	> x 
	   CK  T1  T2 
	1 1.1 2.1 2.5 
	2 1.2 2.2 2.2 
	3 1.1 2.3 2.3 
	4 1.5 2.1 2.1 

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

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

  而unstack的作用正好和stack相反,但是要注意它的第二个参数是公式类型:公式左边的变量是值,右边的变量会被当成因子类型,它的每个水平都会形成一列:

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

参考资料

posted @ 2016-05-30 00:34  银河统计  阅读(2071)  评论(0编辑  收藏  举报