R_Split-Apply-combine
2015-09-01 17:05
155 查看
昨天看到豆瓣上一篇文章,是作者关于读Hadley Wickham的文章The Split-Apply-Combine Strategy for Data Analysis的笔记。
文章地址
自己在用R整理数据的时候,为了避免显示循环,使用apply函数族的时候,常常遇到输入类型和输出类型搞混的情况,这篇文章对R base中的 split-apply-combine有一个很好的整理。以及介绍了R社区中数据整理大牛Wickham的一个R包-plyr。
plyr包是Hadley Wickham为解决split – apply – combine问题而写的一个包,其动机在与提供超越for循环和内置的apply函数族的一个一揽子解决方案。使用plyr包可以针对不同的数据类型,在一个函数内同时完成split – apply – combine三个步骤,以实现最大限度的高效和简洁。
plyr包特别适合处理大型数据集问题,比如对空间数据的空间位置或时间序列面板数据的时间点建模,或者在高维数组中进行数据探索等等。
数据转换常用的一个模式:split-apply-combine。具体的说就是:将一个大数据分拆成小块,在每一个小块内进行操作,合并操作结果。
split(x,f)其中x是待分组的向量、矩阵、数据框,f是分组因子,返回值是一个列表。
Example1:对向量分组
可以看出返回值是一个列表。
Example2:对矩阵分组
Example3:对数据框分组
unsplit()函数是split()函数的逆函数,可以使分组和好如初。
subset()取子集的一个函数
cut()划分数值变量的取值
strsplit()分割字符变量
apply :Apply Functions Over Array Margins
by :Apply a Function to a Data Frame Split by Factors
eapply :Apply a Function Over Values in an Environment
lapply :Apply a Function over a List or Vector
mapply :Apply a Function to Multiple List or Vector Arguments
rapply :Recursively Apply a Function to a List
tapply :Apply a Function Over a Ragged Array
除此之外,还有可作为lapply变形的sapply,vapply和 replicate,共计10个函数。
apply()函数作用于数组、矩阵、数据框,对行或者列作用,返回一个向量、数组或者列表
by函数矩阵或者数据框,作用于按行分组的子集,返回一个列表或者数组。它是tapply的友好版
lapply作用于列表或者向量使用函数,返回一个列表
sapply是lapply的用户友好版,如何合适的话,可以返回一个向量或者矩阵
vapply类似sapply,可以预先定义返回值的类型
mapply()作用于多重列表或者是向量参数
rapply()递归的应用一个函数到列表 (可以认为是作用于列表中的每一个元素?)
tapply()对不规则的数组按确定的因子计算函数
文章地址
自己在用R整理数据的时候,为了避免显示循环,使用apply函数族的时候,常常遇到输入类型和输出类型搞混的情况,这篇文章对R base中的 split-apply-combine有一个很好的整理。以及介绍了R社区中数据整理大牛Wickham的一个R包-plyr。
plyr包是Hadley Wickham为解决split – apply – combine问题而写的一个包,其动机在与提供超越for循环和内置的apply函数族的一个一揽子解决方案。使用plyr包可以针对不同的数据类型,在一个函数内同时完成split – apply – combine三个步骤,以实现最大限度的高效和简洁。
plyr包特别适合处理大型数据集问题,比如对空间数据的空间位置或时间序列面板数据的时间点建模,或者在高维数组中进行数据探索等等。
数据转换常用的一个模式:split-apply-combine。具体的说就是:将一个大数据分拆成小块,在每一个小块内进行操作,合并操作结果。
split
函数split()可以按照分组因子,把向量,矩阵和数据框进行适当的分组。它的返回值是一个列表,代表分组变量每个水平的观测。这个列表可以使用sapply(),lappy()进行处理(apply – combine步骤),得到问题的最终结果。split(x,f)其中x是待分组的向量、矩阵、数据框,f是分组因子,返回值是一个列表。
Example1:对向量分组
n <- 10 nn <- 100 g <- factor(round(n * runif(n * nn))) #runif产生均匀分布,默认参数是0-1之间的。 x <- rnorm(n * nn) + sqrt(as.numeric(g)) xg <- split(x, g) str(xg)
List of 11 $ 0 : num [1:50] 1.858 1.999 0.503 2.771 1.624 ... $ 1 : num [1:108] 1.836 1.428 1.432 -0.332 2.857 ... $ 2 : num [1:100] 0.162 2.657 0.151 0.212 1.906 ... $ 3 : num [1:103] 1.16 1.78 3.24 1.9 1.18 ... $ 4 : num [1:104] 3.46 2.58 2.5 3.36 1.97 ... $ 5 : num [1:87] 2.99 2.21 3.39 2.47 2.37 ... $ 6 : num [1:107] 2.88 1.79 1.85 4.14 3.48 ... $ 7 : num [1:82] 4.32 3.34 2.62 2.01 4.02 ... $ 8 : num [1:93] 1.67 5.11 2.8 1.83 2.52 ... $ 9 : num [1:123] 3.6 4.72 2.08 2.32 1.78 ... $ 10: num [1:43] 4.14 1.29 4.14 3.29 3.55 ...
可以看出返回值是一个列表。
Example2:对矩阵分组
a <- matrix(c(1:20, rep(1:2, 5)), ncol = 3) #产生一个三列的矩阵 a
[,1] [,2] [,3] [1,] 1 11 1 [2,] 2 12 2 [3,] 3 13 1 [4,] 4 14 2 [5,] 5 15 1 [6,] 6 16 2 [7,] 7 17 1 [8,] 8 18 2 [9,] 9 19 1 [10,] 10 20 2
b <- split(a, col(a)) # 案列分组 b
$`1` [1] 1 2 3 4 5 6 7 8 9 10 $`2` [1] 11 12 13 14 15 16 17 18 19 20 $`3` [1] 1 2 1 2 1 2 1 2 1 2
c <- split(a[, -3], factor(a[, 3])) #按照第三列分组 c
$`1` [1] 1 3 5 7 9 11 13 15 17 19 $`2` [1] 2 4 6 8 10 12 14 16 18 20
Example3:对数据框分组
a <- data.frame(a = 1:10, b = 11:20, c = rep(1:2, each = 5)) #产生一个三列的数据框 a
a b c 1 1 11 1 2 2 12 1 3 3 13 1 4 4 14 1 5 5 15 1 6 6 16 2 7 7 17 2 8 8 18 2 9 9 19 2 10 10 20 2
b <- split(a, a$c) #按照第三列分组 b
$`1` a b c 1 1 11 1 2 2 12 1 3 3 13 1 4 4 14 1 5 5 15 1 $`2` a b c 6 6 16 2 7 7 17 2 8 8 18 2 9 9 19 2 10 10 20 2
unsplit()函数是split()函数的逆函数,可以使分组和好如初。
subset()取子集的一个函数
str(airquality)
'data.frame': 153 obs. of 6 variables: $ Ozone : int 41 36 12 18 NA 28 23 19 8 NA ... $ Solar.R: int 190 118 149 313 NA NA 299 99 19 194 ... $ Wind : num 7.4 8 12.6 11.5 14.3 14.9 8.6 13.8 20.1 8.6 ... $ Temp : int 67 72 74 62 56 66 65 59 61 69 ... $ Month : int 5 5 5 5 5 5 5 5 5 5 ... $ Day : int 1 2 3 4 5 6 7 8 9 10 ...
head(subset(airquality, Temp > 80, select = c(Ozone, Temp)))
Ozone Temp 29 45 81 35 NA 84 36 NA 85 38 29 82 39 NA 87 40 71 90
cut()划分数值变量的取值
strsplit()分割字符变量
apply函数族
aplly函数族主要用来完成apply-combine过程,该函数族的使用经常让我混乱。apply :Apply Functions Over Array Margins
by :Apply a Function to a Data Frame Split by Factors
eapply :Apply a Function Over Values in an Environment
lapply :Apply a Function over a List or Vector
mapply :Apply a Function to Multiple List or Vector Arguments
rapply :Recursively Apply a Function to a List
tapply :Apply a Function Over a Ragged Array
除此之外,还有可作为lapply变形的sapply,vapply和 replicate,共计10个函数。
apply()函数作用于数组、矩阵、数据框,对行或者列作用,返回一个向量、数组或者列表
by函数矩阵或者数据框,作用于按行分组的子集,返回一个列表或者数组。它是tapply的友好版
lapply作用于列表或者向量使用函数,返回一个列表
sapply是lapply的用户友好版,如何合适的话,可以返回一个向量或者矩阵
vapply类似sapply,可以预先定义返回值的类型
i39 <- sapply(3:9, seq) # list of vectors sapply(i39, fivenum)
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] ## [1,] 1.0 1.0 1 1.0 1.0 1.0 1 ## [2,] 1.5 1.5 2 2.0 2.5 2.5 3 ## [3,] 2.0 2.5 3 3.5 4.0 4.5 5 ## [4,] 2.5 3.5 4 5.0 5.5 6.5 7 ## [5,] 3.0 4.0 5 6.0 7.0 8.0 9
vapply(i39, fivenum, c(Min. = 0, `1st Qu.` = 0, Median = 0, `3rd Qu.` = 0, Max. = 0))
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] ## Min. 1.0 1.0 1 1.0 1.0 1.0 1 ## 1st Qu. 1.5 1.5 2 2.0 2.5 2.5 3 ## Median 2.0 2.5 3 3.5 4.0 4.5 5 ## 3rd Qu. 2.5 3.5 4 5.0 5.5 6.5 7 ## Max. 3.0 4.0 5 6.0 7.0 8.0 9
mapply()作用于多重列表或者是向量参数
mapply(rep, 1:4, 4:1)
## [[1]] ## [1] 1 1 1 1 ## ## [[2]] ## [1] 2 2 2 ## ## [[3]] ## [1] 3 3 ## ## [[4]] ## [1] 4
mapply(rep, times = 1:4, x = 4:1)
## [[1]] ## [1] 4 ## ## [[2]] ## [1] 3 3 ## ## [[3]] ## [1] 2 2 2 ## ## [[4]] ## [1] 1 1 1 1
mapply(rep, times = 1:4, MoreArgs = list(x = 42))
## [[1]] ## [1] 42 ## ## [[2]] ## [1] 42 42 ## ## [[3]] ## [1] 42 42 42 ## ## [[4]] ## [1] 42 42 42 42
mapply(function(x, y) seq_len(x) + y, c(a = 1, b = 2, c = 3), # names from first c(A = 10, B = 0, C = -10))
## $a ## [1] 11 ## ## $b ## [1] 1 2 ## ## $c ## [1] -9 -8 -7
word <- function(C, k) paste(rep.int(C, k), collapse = "") utils::str(mapply(word, LETTERS[1:6], 6:1, SIMPLIFY = FALSE))
## List of 6 ## $ A: chr "AAAAAA" ## $ B: chr "BBBBB" ## $ C: chr "CCCC" ## $ D: chr "DDD" ## $ E: chr "EE" ## $ F: chr "F"
rapply()递归的应用一个函数到列表 (可以认为是作用于列表中的每一个元素?)
X <- list(list(a = pi, b = list(c = 1:1)), d = "a test") X
## [[1]] ## [[1]]$a ## [1] 3.142 ## ## [[1]]$b ## [[1]]$b$c ## [1] 1 ## ## ## ## $d ## [1] "a test"
rapply(X, function(x) x, how = "replace")
## [[1]] ## [[1]]$a ## [1] 3.142 ## ## [[1]]$b ## [[1]]$b$c ## [1] 1 ## ## ## ## $d ## [1] "a test"
rapply(X, sqrt, classes = "numeric", how = "replace")
## [[1]] ## [[1]]$a ## [1] 1.772 ## ## [[1]]$b ## [[1]]$b$c ## [1] 1 ## ## ## ## $d ## [1] "a test"
rapply(X, nchar, classes = "character", deflt = as.integer(NA), how = "list")
## [[1]] ## [[1]]$a ## [1] NA ## ## [[1]]$b ## [[1]]$b$c ## [1] NA ## ## ## ## $d ## [1] 6
rapply(X, nchar, classes = "character", deflt = as.integer(NA), how = "unlist")
## a b.c d ## NA NA 6
rapply(X, nchar, classes = "character", how = "unlist")
## d ## 6
rapply(X, log, classes = "numeric", how = "replace", base = 2)
## [[1]] ## [[1]]$a ## [1] 1.651 ## ## [[1]]$b ## [[1]]$b$c ## [1] 1 ## ## ## ## $d ## [1] "a test"
tapply()对不规则的数组按确定的因子计算函数
head(warpbreaks)
## breaks wool tension ## 1 26 A L ## 2 30 A L ## 3 54 A L ## 4 25 A L ## 5 70 A L ## 6 52 A L
tapply(warpbreaks$breaks, warpbreaks[, -1], sum)
## tension ## wool L M H ## A 401 216 221 ## B 254 259 169
plyr包
plyr包函数的命名规则 | array | data.frame | list | nothing |
---|---|---|---|---|
array | aaply | adply | alply | a_ply |
data.frame | daply | ddply | dlply | d_ply |
list | laply | ldply | llply | l_ply |
n replicates | raply | rdply | rlply | r_ply |
function arguments | maply | mdply | mlply | m_ply |
相关文章推荐
- android沉浸式状态栏的实现
- android沉浸式状态栏的实现
- android沉浸式状态栏的实现
- IOS第16天(2,Quartz2D下载进度条)
- android学习笔记(10)service初步
- 常用Android工具(方法)大全
- 14.IOS中系统唯一标识ID
- 15.app preview 上架视频要求
- 转->Unity3D Member data 和 Inspector,Serialize的关系
- Unity3D的SerializeField 序列化域名
- iOS KVC,KVO
- 从今天开始学习cocos 2d js
- [Unity3d]定义自己的鼠标
- 微信开发笔记
- 提高Android开发效率的9个Web工具
- AndroidStudio遇到的奇葩SVN问题
- 4.极光推送解释的iOS本地通知
- 5.iOS 7 Background Remote Notification
- MyBatis——Mapper XML 文件
- cocos2dx设置音量之前一定要tmd播放!!