R語(yǔ)言--向量化計(jì)算(apply族函數(shù))

R語(yǔ)言最優(yōu)秀的是它的向量化編程跟狱,這其中apply族函數(shù)扮演了非常重要的角色寺晌。apply族函數(shù)是由apply世吨、sapply、lapply呻征、mapply耘婚、tapply等函數(shù)組成的。熟練使用apply族函數(shù)陆赋,能夠簡(jiǎn)化程序沐祷,提高代碼的運(yùn)算速度。

apply

apply是最基本的函數(shù)攒岛。為了方便演示戈轿,選取了R自帶的數(shù)據(jù)框mtcars的前4行和前5列,并賦值給data阵子。a1返回的結(jié)果是data數(shù)據(jù)每一行的和,由于每行都有一個(gè)和胜蛉,所以a1是4個(gè)元素組成的數(shù)值向量挠进。a2返回的結(jié)果是data數(shù)據(jù)每一列的均值,同樣誊册,a2是5個(gè)元素組成的數(shù)值向量领突。

# 獲取內(nèi)置數(shù)據(jù)
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
# 對(duì)數(shù)據(jù)框每行求和
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
# 對(duì)數(shù)據(jù)框每列求均值
a2 <- apply(data,2,mean)
print(a2)
##      mpg      cyl     disp       hp     drat 
##  21.5500   5.5000 171.5000 105.7500   3.6825

apply函數(shù)的第一個(gè)參數(shù)表示數(shù)據(jù),第二個(gè)參數(shù)表示維度(1表示行案怯,2表示列)君旦,第三個(gè)參數(shù)表示在維度上操作的函數(shù)。需要注意的是第三個(gè)參數(shù)嘲碱,用作演示的函數(shù)是R自帶的函數(shù)(sum金砍、mean),當(dāng)然麦锯,這里也可以是自己定義的函數(shù)恕稠。

# 自定義函數(shù)(求極差)
func <- function(x){
  result <- diff(range(x))
  return(result)
}
# 對(duì)數(shù)據(jù)框每列求極差
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做演示鹅巍。計(jì)算數(shù)據(jù)框data每列的數(shù)據(jù)范圍千扶,用sapply進(jìn)行計(jì)算,返回的結(jié)果存儲(chǔ)在s1里骆捧,sapply第一個(gè)參數(shù)是需要計(jì)算的數(shù)據(jù)框澎羞,第二個(gè)參數(shù)是函數(shù),第三個(gè)參數(shù)simplify=T(默認(rèn))代表返回的結(jié)果簡(jiǎn)化表示敛苇,s1的數(shù)據(jù)格式為矩陣妆绞。

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

如果不想讓計(jì)算的結(jié)果自動(dòng)合并成矩陣,可以設(shè)置simplify=F接谨,將返回一個(gè)列表摆碉,列表的每個(gè)組件包含了data數(shù)據(jù)框每列的range函數(shù)計(jì)算結(jié)果。

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

sapply一個(gè)更常見的用法是針對(duì)列表的組件進(jìn)行操作脓豪。例如有n個(gè)數(shù)據(jù)框巷帝,對(duì)每個(gè)數(shù)據(jù)框都要進(jìn)行相同的操作,常規(guī)方法用循環(huán)遍歷扫夜,但操作體驗(yàn)差楞泼,速度慢,更優(yōu)的解決方案是:先對(duì)單個(gè)數(shù)據(jù)框定義處理函數(shù)笤闯,然后用sapply對(duì)所有數(shù)據(jù)框采取相同操作堕阔。

# 定義一個(gè)數(shù)據(jù)框組成的list
df_list <- list(a=mtcars[1:3,1:4],
                b=airquality[1:3,1:4],
                c=iris[1:3,1:4])
# 自定義函數(shù)(求數(shù)據(jù)框歐氏距離的最大值)
max_func <- function(x){
  d <- dist(x,p=2)
  return(max(d))
}
# sapply對(duì)每個(gè)數(shù)據(jù)框計(jì)算
s3 <- sapply(df_list,max_func)
print(s3)
##          a          b          c 
## 54.7744466 72.3488770  0.5385165

lapply

lapply的用法與sapply基本相同,只不過返回的結(jié)果是以list儲(chǔ)存的颗味。

# 求每一列的均值
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的基礎(chǔ)上進(jìn)行了拓展超陆,可以應(yīng)用在多個(gè)變量上。a浦马、b时呀、c三個(gè)數(shù)值向量,第一次需要計(jì)算1*2*3晶默,第二次需要計(jì)算2*3*4谨娜,...,以此類推磺陡。當(dāng)需要每次變化的變量有多個(gè)時(shí)趴梢,用mapply計(jì)算更方便快捷。

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主要用在分組計(jì)算上币他。分組計(jì)算是常見的數(shù)據(jù)處理操作坞靶,能夠處理分組計(jì)算的函數(shù)也不少,tapply的優(yōu)勢(shì)是簡(jiǎn)單便捷圆丹。

# 數(shù)據(jù)框
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
# 按照l(shuí)abel分組計(jì)算value和
t1 <- tapply(X =group_df$value,INDEX = group_df$label,sum)
print(t1)
##  a  b 
##  9 12
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末滩愁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辫封,更是在濱河造成了極大的恐慌硝枉,老刑警劉巖廉丽,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異妻味,居然都是意外死亡正压,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門责球,熙熙樓的掌柜王于貴愁眉苦臉地迎上來焦履,“玉大人,你說我怎么就攤上這事雏逾〖慰悖” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵栖博,是天一觀的道長(zhǎng)屑宠。 經(jīng)常有香客問我,道長(zhǎng)仇让,這世上最難降的妖魔是什么典奉? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮丧叽,結(jié)果婚禮上卫玖,老公的妹妹穿的比我還像新娘。我一直安慰自己踊淳,他們只是感情好假瞬,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迂尝,像睡著了一般笨触。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上雹舀,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音粗俱,去河邊找鬼说榆。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寸认,可吹牛的內(nèi)容都是我干的签财。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼偏塞,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼唱蒸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起灸叼,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤神汹,失蹤者是張志新(化名)和其女友劉穎庆捺,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體屁魏,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滔以,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了氓拼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片你画。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖桃漾,靈堂內(nèi)的尸體忽然破棺而出坏匪,到底是詐尸還是另有隱情,我是刑警寧澤撬统,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布适滓,位于F島的核電站,受9級(jí)特大地震影響宪摧,放射性物質(zhì)發(fā)生泄漏粒竖。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一几于、第九天 我趴在偏房一處隱蔽的房頂上張望蕊苗。 院中可真熱鬧,春花似錦沿彭、人聲如沸朽砰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瞧柔。三九已至,卻和暖如春睦裳,著一層夾襖步出監(jiān)牢的瞬間造锅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工廉邑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哥蔚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓蛛蒙,卻偏偏與公主長(zhǎng)得像糙箍,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子牵祟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容