R语言--向量化计算(apply族函数)

R语言最优秀的是它的向量化编程,这其中apply族函数扮演了非常重要的角色。apply族函数是由apply、sapply、lapply、mapply、tapply等函数组成的。熟练使用apply族函数,能够简化程序,提高代码的运算速度。

apply

apply是最基本的函数。为了方便演示,选取了R自带的数据框mtcars的前4行和前5列,并赋值给data。a1返回的结果是data数据每一行的和,由于每行都有一个和,所以a1是4个元素组成的数值向量。a2返回的结果是data数据每一列的均值,同样,a2是5个元素组成的数值向量。

# 获取内置数据
data <- mtcars[1:4,1:5]
print(data) 
##                 mpg cyl disp  hp drat
## Mazda RX4      21.0   6  160 110 3.90
## Mazda RX4 Wag  21.0   6  160 110 3.90
## Datsun 710     22.8   4  108  93 3.85
## Hornet 4 Drive 21.4   6  258 110 3.08
# 对数据框每行求和
a1 <- apply(data,1,sum)
print(a1)
##      Mazda RX4  Mazda RX4 Wag     Datsun 710 Hornet 4 Drive 
##         300.90         300.90         231.65         398.48
# 对数据框每列求均值
a2 <- apply(data,2,mean)
print(a2)
##      mpg      cyl     disp       hp     drat 
##  21.5500   5.5000 171.5000 105.7500   3.6825

apply函数的第一个参数表示数据,第二个参数表示维度(1表示行,2表示列),第三个参数表示在维度上操作的函数。需要注意的是第三个参数,用作演示的函数是R自带的函数(sum、mean),当然,这里也可以是自己定义的函数。

# 自定义函数(求极差)
func <- function(x){
  result <- diff(range(x))
  return(result)
}
# 对数据框每列求极差
a3 <- apply(data,2,func)
print(a3)
##    mpg    cyl   disp     hp   drat 
##   1.80   2.00 150.00  17.00   0.82

sapply

sapply的用法比apply要更灵活一些,同样,用data做演示。计算数据框data每列的数据范围,用sapply进行计算,返回的结果存储在s1里,sapply第一个参数是需要计算的数据框,第二个参数是函数,第三个参数simplify=T(默认)代表返回的结果简化表示,s1的数据格式为矩阵。

s1 <- sapply(data,range,simplify = T)
class(s1)
## [1] "matrix"

如果不想让计算的结果自动合并成矩阵,可以设置simplify=F,将返回一个列表,列表的每个组件包含了data数据框每列的range函数计算结果。

s2 <- sapply(data,range,simplify = F)
class(s2)
## [1] "list"

sapply一个更常见的用法是针对列表的组件进行操作。例如有n个数据框,对每个数据框都要进行相同的操作,常规方法用循环遍历,但操作体验差,速度慢,更优的解决方案是:先对单个数据框定义处理函数,然后用sapply对所有数据框采取相同操作

# 定义一个数据框组成的list
df_list <- list(a=mtcars[1:3,1:4],
                b=airquality[1:3,1:4],
                c=iris[1:3,1:4])
# 自定义函数(求数据框欧氏距离的最大值)
max_func <- function(x){
  d <- dist(x,p=2)
  return(max(d))
}
# sapply对每个数据框计算
s3 <- sapply(df_list,max_func)
print(s3)
##          a          b          c 
## 54.7744466 72.3488770  0.5385165

lapply

lapply的用法与sapply基本相同,只不过返回的结果是以list储存的。

# 求每一列的均值
l1 <- lapply(data,mean) 
print(l1)
## $mpg
## [1] 21.55
## 
## $cyl
## [1] 5.5
## 
## $disp
## [1] 171.5
## 
## $hp
## [1] 105.75
## 
## $drat
## [1] 3.6825
class(l1) 
## [1] "list"

mapply

mapply在sapply和lapply的基础上进行了拓展,可以应用在多个变量上。a、b、c三个数值向量,第一次需要计算1*2*3,第二次需要计算2*3*4,...,以此类推。当需要每次变化的变量有多个时,用mapply计算更方便快捷。

a <- 1:5
b <- 2:6
c <- 3:7
m1 <- mapply(prod,a,b,c)
print(m1)
## [1]   6  24  60 120 210

tapply

tapply主要用在分组计算上。分组计算是常见的数据处理操作,能够处理分组计算的函数也不少,tapply的优势是简单便捷。

# 数据框
group_df <- data.frame(value=1:6,label=rep(c("a","b"),3,each=1))
print(group_df)
##   value label
## 1     1     a
## 2     2     b
## 3     3     a
## 4     4     b
## 5     5     a
## 6     6     b
# 按照label分组计算value和
t1 <- tapply(X =group_df$value,INDEX = group_df$label,sum)
print(t1)
##  a  b 
##  9 12
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,923评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,154评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,775评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,960评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,976评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,972评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,893评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,709评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,159评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,400评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,552评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,265评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,876评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,528评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,701评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,552评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,451评论 2 352

推荐阅读更多精彩内容