《Learning R》笔记 Chapter 9 中 隐式循环

2018-02-22  本文已影响0人  天火燎原天

在array中进行隐式循环

lapply,vapply和sapply不能直接用于matrix等array中,这3个函数会将array视作vector,沿着column的方向将每个元素运算一次,因此对于array结果的数据,我们需要使用apply()函数。

apply(X, MARGIN, FUN, ...)
#MARGIN取1为row,取2为col

需要注意的是,apply函数的每一轮循环输出结果都会被as.vector()强行coerce一次,然后再根据结果长短是否一致最终输出为matrix或list。换句话说,如果隐循环每一轮本来输出的是factor,被强行coerce之后输出的就是character了,最终结果是一个character matrix。

> x=matrix(1:16,nrow = 4)
> apply(x, 1, toString) #输出的是4元素的string
[1] "1, 5, 9, 13"  "2, 6, 10, 14" "3, 7, 11, 15" "4, 8, 12, 16"

在dataframe中进行隐式循环

正如前文所说,dataframe是list和array的结合体,因此sapply和apply都可以用于dataframe,但依然要时刻留意格式coerce可能造成的隐患。

多参数同时进入隐式循环

mapply()可以接受多个参数同时进入循环,但其参数传递的顺序需要注意。

#FUN是第一个传递进入的参数
mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE,
       USE.NAMES = TRUE)

参数化函数

Vectorize()是一个wrapper,可以将某些不能接受vector类型参数的函数(通常为自定义)转化为能够接受vector参数的函数。

split() 和 tapply()

书中介绍了split()函数和tapply函数。但个人认为使用reshape2包中的melt()或cast()函数先把数据源处理了可能更好。。。。
split输出一个list

# split能够接受新的vector输入
split(x, f, drop = FALSE, ...)
## Default S3 method:
split(x, f, drop = FALSE, sep = ".", lex.order = FALSE, ...)
split(x, f, drop = FALSE, ...) <- value
unsplit(value, f, drop = FALSE)

而tapply是针对ragged array进行了优化的一类apply函数。

Apply a function to each cell of a ragged array, that is to each (non-empty) group of values 
given by a unique combination of the levels of certain factors.

tapply(X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE)
#相当于split X by INDEX中的factor levels then apply FUN
#INDEX参数会被强行as.factor()

tapply()的两个wrapper

by()和aggregate()是tapply的两个warpper函数。by()适用于dataframe;而aggregate可用于dataframe,formula和ts三种数据类型。

by(data, INDICES, FUN, ..., simplify = TRUE)
## S3 method for class 'data.frame'
aggregate(x, by, FUN, ..., simplify = TRUE, drop = TRUE)
上一篇下一篇

猜你喜欢

热点阅读