99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁(yè)精彩閱讀掌握R語(yǔ)言中的apply函數(shù)族
掌握R語(yǔ)言中的apply函數(shù)族
2017-07-22
收藏

掌握R語(yǔ)言中的apply函數(shù)族

剛開(kāi)始接觸R語(yǔ)言時(shí),會(huì)聽(tīng)到各種的R語(yǔ)言使用技巧,其中最重要的一條就是不要用循環(huán),效率特別低,要用向量計(jì)算代替循環(huán)計(jì)算。

那么,這是為什么呢?原因在于R的循環(huán)操作for和while,都是基于R語(yǔ)言本身來(lái)實(shí)現(xiàn)的,而向量操作是基于底層的C語(yǔ)言函數(shù)實(shí)現(xiàn)的,從性能上來(lái)看,就會(huì)有比較明顯的差距了。那么如何使用C的函數(shù)來(lái)實(shí)現(xiàn)向量計(jì)算呢,就是要用到apply的家族函數(shù),包括apply, sapply, tapply, mapply, lapply, rapply, vapply, eapply等。

1. apply的家族函數(shù)

apply函數(shù)族是R語(yǔ)言中數(shù)據(jù)處理的一組核心函數(shù),通過(guò)使用apply函數(shù),我們可以實(shí)現(xiàn)對(duì)數(shù)據(jù)的循環(huán)、分組、過(guò)濾、類型控制等操作。但是,由于在R語(yǔ)言中apply函數(shù)與其他語(yǔ)言循環(huán)體的處理思路是完全不一樣的,所以apply函數(shù)族一直是使用者玩不轉(zhuǎn)一類核心函數(shù)。

很多R語(yǔ)言新手,寫了很多的for循環(huán)代碼,也不愿意多花點(diǎn)時(shí)間把a(bǔ)pply函數(shù)的使用方法了解清楚,最后把R代碼寫的跟C似得,我嚴(yán)重鄙視只會(huì)寫for的R程序員。

apply函數(shù)本身就是解決數(shù)據(jù)循環(huán)處理的問(wèn)題,為了面向不同的數(shù)據(jù)類型,不同的返回值,apply函數(shù)組成了一個(gè)函數(shù)族,包括了8個(gè)功能類似的函數(shù)。這其中有些函數(shù)很相似,有些也不是太一樣的。

apply

我一般最常用的函數(shù)為apply和sapply,下面將分別介紹這8個(gè)函數(shù)的定義和使用方法。

2. apply函數(shù)

apply函數(shù)是最常用的代替for循環(huán)的函數(shù)。apply函數(shù)可以對(duì)矩陣、數(shù)據(jù)框、數(shù)組(二維、多維),按行或列進(jìn)行循環(huán)計(jì)算,對(duì)子元素進(jìn)行迭代,并把子元素以參數(shù)傳遞的形式給自定義的FUN函數(shù)中,并以返回計(jì)算結(jié)果。

函數(shù)定義:

apply(X, MARGIN, FUN, ...)

參數(shù)列表:

X:數(shù)組、矩陣、數(shù)據(jù)框

MARGIN: 按行計(jì)算或按按列計(jì)算,1表示按行,2表示按列

FUN: 自定義的調(diào)用函數(shù)

…: 更多參數(shù),可選

比如,對(duì)一個(gè)矩陣的每一行求和,下面就要用到apply做循環(huán)了。

> x<-matrix(1:12,ncol=3) > apply(x,1,sum) [1] 15 18 21 24

下面計(jì)算一個(gè)稍微復(fù)雜點(diǎn)的例子,按行循環(huán),讓數(shù)據(jù)框的x1列加1,并計(jì)算出x1,x2列的均值。

# 生成data.frame > x <- cbind(x1 = 3, x2 = c(4:1, 2:5)); x x1 x2 [1,] 3 4 [2,] 3 3 [3,] 3 2 [4,] 3 1 [5,] 3 2 [6,] 3 3 [7,] 3 4 [8,] 3 5 # 自定義函數(shù)myFUN,第一個(gè)參數(shù)x為數(shù)據(jù) # 第二、三個(gè)參數(shù)為自定義參數(shù),可以通過(guò)apply的'...'進(jìn)行傳入。 > myFUN<- function(x, c1, c2) { + c(sum(x[c1],1), mean(x[c2])) + } # 把數(shù)據(jù)框按行做循環(huán),每行分別傳遞給myFUN函數(shù),設(shè)置c1,c2對(duì)應(yīng)myFUN的第二、三個(gè)參數(shù) > apply(x,1,myFUN,c1='x1',c2=c('x1','x2')) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [1,] 4.0 4 4.0 4 4.0 4 4.0 4 [2,] 3.5 3 2.5 2 2.5 3 3.5 4

通過(guò)這個(gè)上面的自定義函數(shù)myFUN就實(shí)現(xiàn)了,一個(gè)常用的循環(huán)計(jì)算。

如果直接用for循環(huán)來(lái)實(shí)現(xiàn),那么代碼如下:

# 定義一個(gè)結(jié)果的數(shù)據(jù)框 > df<-data.frame() # 定義for循環(huán) > for(i in 1:nrow(x)){ + row<-x[i,] # 每行的值 + df<-rbind(df,rbind(c(sum(row[1],1), mean(row)))) # 計(jì)算,并賦值到結(jié)果數(shù)據(jù)框 + } # 打印結(jié)果數(shù)據(jù)框 > df V1 V2 1 4 3.5 2 4 3.0 3 4 2.5 4 4 2.0 5 4 2.5 6 4 3.0 7 4 3.5 8 4 4.0

通過(guò)for循環(huán)的方式,也可以很容易的實(shí)現(xiàn)上面計(jì)算過(guò)程,但是這里還有一些額外的操作需要自己處理,比如構(gòu)建循環(huán)體、定義結(jié)果數(shù)據(jù)集、并合每次循環(huán)的結(jié)果到結(jié)果數(shù)據(jù)集。

對(duì)于上面的需求,還有第三種實(shí)現(xiàn)方法,那就是完成利用了R的特性,通過(guò)向量化計(jì)算來(lái)完成的。

> data.frame(x1=x[,1]+1,x2=rowMeans(x)) x1 x2 1 4 3.5 2 4 3.0 3 4 2.5 4 4 2.0 5 4 2.5 6 4 3.0 7 4 3.5 8 4 4.0

那么,一行就可以完成整個(gè)計(jì)算過(guò)程了。

接下來(lái),我們需要再比較一下3種操作上面性能上的消耗。

# 清空環(huán)境變量 > rm(list=ls()) # 封裝fun1 > fun1<-function(x){ + myFUN<- function(x, c1, c2) { + c(sum(x[c1],1), mean(x[c2])) + } + apply(x,1,myFUN,c1='x1',c2=c('x1','x2')) + } # 封裝fun2 > fun2<-function(x){ + df<-data.frame() + for(i in 1:nrow(x)){ + row<-x[i,] + df<-rbind(df,rbind(c(sum(row[1],1), mean(row)))) + } + } # 封裝fun3 > fun3<-function(x){ + data.frame(x1=x[,1]+1,x2=rowMeans(x)) + } # 生成數(shù)據(jù)集 > x <- cbind(x1=3, x2 = c(400:1, 2:500)) # 分別統(tǒng)計(jì)3種方法的CPU耗時(shí)。 > system.time(fun1(x)) 用戶 系統(tǒng) 流逝 0.01 0.00 0.02 > system.time(fun2(x)) 用戶 系統(tǒng) 流逝 0.19 0.00 0.18 > system.time(fun3(x)) 用戶 系統(tǒng) 流逝 0 0 0

從CPU的耗時(shí)來(lái)看,用for循環(huán)實(shí)現(xiàn)的計(jì)算是耗時(shí)最長(zhǎng)的,apply實(shí)現(xiàn)的循環(huán)耗時(shí)很短,而直接使用R語(yǔ)言內(nèi)置的向量計(jì)算的操作幾乎不耗時(shí)。通過(guò)上面的測(cè)試,對(duì)同一個(gè)計(jì)算來(lái)說(shuō),優(yōu)先考慮R語(yǔ)言內(nèi)置的向量計(jì)算,必須要用到循環(huán)時(shí)則使用apply函數(shù),應(yīng)該盡量避免顯示的使用for,while等操作方法。

3. lapply函數(shù)

lapply函數(shù)是一個(gè)最基礎(chǔ)循環(huán)操作函數(shù)之一,用來(lái)對(duì)list、data.frame數(shù)據(jù)集進(jìn)行循環(huán),并返回和X長(zhǎng)度同樣的list結(jié)構(gòu)作為結(jié)果集,通過(guò)lapply的開(kāi)頭的第一個(gè)字母’l’就可以判斷返回結(jié)果集的類型。

函數(shù)定義:

lapply(X, FUN, ...)

參數(shù)列表:

X:list、data.frame數(shù)據(jù)

FUN: 自定義的調(diào)用函數(shù)

…: 更多參數(shù),可選

比如,計(jì)算list中的每個(gè)KEY對(duì)應(yīng)該的數(shù)據(jù)的分位數(shù)。

# 構(gòu)建一個(gè)list數(shù)據(jù)集x,分別包括a,b,c 三個(gè)KEY值。 > x <- list(a = 1:10, b = rnorm(6,10,5), c = c(TRUE,FALSE,FALSE,TRUE));x $a [1] 1 2 3 4 5 6 7 8 9 10 $b [1] 0.7585424 14.3662366 13.3772979 11.6658990 9.7011387 21.5321427 $c [1] TRUE FALSE FALSE TRUE # 分別計(jì)算每個(gè)KEY對(duì)應(yīng)該的數(shù)據(jù)的分位數(shù)。 > lapply(x,fivenum) $a [1] 1.0 3.0 5.5 8.0 10.0 $b [1] 0.7585424 9.7011387 12.5215985 14.3662366 21.5321427 $c [1] 0.0 0.0 0.5 1.0 1.0

lapply就可以很方便地把list數(shù)據(jù)集進(jìn)行循環(huán)操作了,還可以用data.frame數(shù)據(jù)集按列進(jìn)行循環(huán),但如果傳入的數(shù)據(jù)集是一個(gè)向量或矩陣對(duì)象,那么直接使用lapply就不能達(dá)到想要的效果了。

比如,對(duì)矩陣的列求和。

# 生成一個(gè)矩陣 > x <- cbind(x1=3, x2=c(2:1,4:5)) > x; class(x) x1 x2 [1,] 3 2 [2,] 3 1 [3,] 3 4 [4,] 3 5 [1] "matrix" # 求和 > lapply(x, sum) [[1]] [1] 3 [[2]] [1] 3 [[3]] [1] 3 [[4]] [1] 3 [[5]] [1] 2 [[6]] [1] 1 [[7]] [1] 4 [[8]] [1] 5

lapply會(huì)分別循環(huán)矩陣中的每個(gè)值,而不是按行或按列進(jìn)行分組計(jì)算。

如果對(duì)數(shù)據(jù)框的列求和。

> lapply(data.frame(x), sum) $x1 [1] 12 $x2 [1] 12

lapply會(huì)自動(dòng)把數(shù)據(jù)框按列進(jìn)行分組,再進(jìn)行計(jì)算。

4. sapply函數(shù)

sapply函數(shù)是一個(gè)簡(jiǎn)化版的lapply,sapply增加了2個(gè)參數(shù)simplify和USE.NAMES,主要就是讓輸出看起來(lái)更友好,返回值為向量,而不是list對(duì)象。

函數(shù)定義:

sapply(X, FUN, ..., simplify=TRUE, USE.NAMES = TRUE)

參數(shù)列表:

X:數(shù)組、矩陣、數(shù)據(jù)框

FUN: 自定義的調(diào)用函數(shù)

…: 更多參數(shù),可選

simplify: 是否數(shù)組化,當(dāng)值array時(shí),輸出結(jié)果按數(shù)組進(jìn)行分組

USE.NAMES: 如果X為字符串,TRUE設(shè)置字符串為數(shù)據(jù)名,F(xiàn)ALSE不設(shè)置

我們還用上面lapply的計(jì)算需求進(jìn)行說(shuō)明。

> x <- cbind(x1=3, x2=c(2:1,4:5)) # 對(duì)矩陣計(jì)算,計(jì)算過(guò)程同lapply函數(shù) > sapply(x, sum) [1] 3 3 3 3 2 1 4 5 # 對(duì)數(shù)據(jù)框計(jì)算 > sapply(data.frame(x), sum) x1 x2 12 12 # 檢查結(jié)果類型,sapply返回類型為向量,而lapply的返回類型為list > class(lapply(x, sum)) [1] "list" > class(sapply(x, sum)) [1] "numeric"

如果simplify=FALSE和USE.NAMES=FALSE,那么完全sapply函數(shù)就等于lapply函數(shù)了。

> lapply(data.frame(x), sum) $x1 [1] 12 $x2 [1] 12 > sapply(data.frame(x), sum, simplify=FALSE, USE.NAMES=FALSE) $x1 [1] 12 $x2 [1] 12

對(duì)于simplify為array時(shí),我們可以參考下面的例子,構(gòu)建一個(gè)三維數(shù)組,其中二個(gè)維度為方陣。

> a<-1:2 # 按數(shù)組分組 > sapply(a,function(x) matrix(x,2,2), simplify='array') , , 1 [,1] [,2] [1,] 1 1 [2,] 1 1 , , 2 [,1] [,2] [1,] 2 2 [2,] 2 2 # 默認(rèn)情況,則自動(dòng)合并分組 > sapply(a,function(x) matrix(x,2,2)) [,1] [,2] [1,] 1 2 [2,] 1 2 [3,] 1 2 [4,] 1 2

對(duì)于字符串的向量,還可以自動(dòng)生成數(shù)據(jù)名。

> val<-head(letters) # 默認(rèn)設(shè)置數(shù)據(jù)名 > sapply(val,paste,USE.NAMES=TRUE) a b c d e f "a" "b" "c" "d" "e" "f" # USE.NAMES=FALSE,則不設(shè)置數(shù)據(jù)名 > sapply(val,paste,USE.NAMES=FALSE) [1] "a" "b" "c" "d" "e" "f"

5. vapply函數(shù)

vapply類似于sapply,提供了FUN.VALUE參數(shù),用來(lái)控制返回值的行名,這樣可以讓程序更健壯。

函數(shù)定義:

vapply(X, FUN, FUN.VALUE, ..., USE.NAMES = TRUE)

參數(shù)列表:

X:數(shù)組、矩陣、數(shù)據(jù)框

FUN: 自定義的調(diào)用函數(shù)

FUN.VALUE: 定義返回值的行名row.names

…: 更多參數(shù),可選

USE.NAMES: 如果X為字符串,TRUE設(shè)置字符串為數(shù)據(jù)名,F(xiàn)ALSE不設(shè)置

比如,對(duì)數(shù)據(jù)框的數(shù)據(jù)進(jìn)行累計(jì)求和,并對(duì)每一行設(shè)置行名row.names

# 生成數(shù)據(jù)集 > x <- data.frame(cbind(x1=3, x2=c(2:1,4:5))) # 設(shè)置行名,4行分別為a,b,c,d > vapply(x,cumsum,FUN.VALUE=c('a'=0,'b'=0,'c'=0,'d'=0)) x1 x2 a 3 2 b 6 3 c 9 7 d 12 12 # 當(dāng)不設(shè)置時(shí),為默認(rèn)的索引值 > a<-sapply(x,cumsum);a x1 x2 [1,] 3 2 [2,] 6 3 [3,] 9 7 [4,] 12 12 # 手動(dòng)的方式設(shè)置行名 > row.names(a)<-c('a','b','c','d') > a x1 x2 a 3 2 b 6 3 c 9 7 d 12 12

通過(guò)使用vapply可以直接設(shè)置返回值的行名,這樣子做其實(shí)可以節(jié)省一行的代碼,讓代碼看起來(lái)更順暢,當(dāng)然如果不愿意多記一個(gè)函數(shù),那么也可以直接忽略它,只用sapply就夠了。

6. mapply函數(shù)

mapply也是sapply的變形函數(shù),類似多變量的sapply,但是參數(shù)定義有些變化。第一參數(shù)為自定義的FUN函數(shù),第二個(gè)參數(shù)’…’可以接收多個(gè)數(shù)據(jù),作為FUN函數(shù)的參數(shù)調(diào)用。

函數(shù)定義:

mapply(FUN, ..., MoreArgs = NULL, SIMPLIFY = TRUE,USE.NAMES = TRUE)

參數(shù)列表:

FUN: 自定義的調(diào)用函數(shù)

…: 接收多個(gè)數(shù)據(jù)

MoreArgs: 參數(shù)列表

SIMPLIFY: 是否數(shù)組化,當(dāng)值array時(shí),輸出結(jié)果按數(shù)組進(jìn)行分組

USE.NAMES: 如果X為字符串,TRUE設(shè)置字符串為數(shù)據(jù)名,F(xiàn)ALSE不設(shè)置

比如,比較3個(gè)向量大小,按索引順序取較大的值。

> set.seed(1) # 定義3個(gè)向量 > x<-1:10 > y<-5:-4 > z<-round(runif(10,-5,5)) # 按索引順序取較大的值。 > mapply(max,x,y,z) [1] 5 4 3 4 5 6 7 8 9 10

再看一個(gè)例子,生成4個(gè)符合正態(tài)分布的數(shù)據(jù)集,分別對(duì)應(yīng)的均值和方差為c(1,10,100,1000)。

> set.seed(1) # 長(zhǎng)度為4 > n<-rep(4,4) # m為均值,v為方差 > m<-v<-c(1,10,100,1000) # 生成4組數(shù)據(jù),按列分組 > mapply(rnorm,n,m,v) [,1] [,2] [,3] [,4] [1,] 0.3735462 13.295078 157.57814 378.7594 [2,] 1.1836433 1.795316 69.46116 -1214.6999 [3,] 0.1643714 14.874291 251.17812 2124.9309 [4,] 2.5952808 17.383247 138.98432 955.0664

由于mapply是可以接收多個(gè)參數(shù)的,所以我們?cè)谧鰯?shù)據(jù)操作的時(shí)候,就不需要把數(shù)據(jù)先合并為data.frame了,直接一次操作就能計(jì)算出結(jié)果了。

7. tapply函數(shù)

tapply用于分組的循環(huán)計(jì)算,通過(guò)INDEX參數(shù)可以把數(shù)據(jù)集X進(jìn)行分組,相當(dāng)于group by的操作。

函數(shù)定義:

tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)

參數(shù)列表:

X: 向量

INDEX: 用于分組的索引

FUN: 自定義的調(diào)用函數(shù)

…: 接收多個(gè)數(shù)據(jù)

simplify : 是否數(shù)組化,當(dāng)值array時(shí),輸出結(jié)果按數(shù)組進(jìn)行分組

比如,計(jì)算不同品種的鳶尾花的花瓣(iris)長(zhǎng)度的均值。

# 通過(guò)iris$Species品種進(jìn)行分組 > tapply(iris$Petal.Length,iris$Species,mean) setosa versicolor virginica 1.462 4.260 5.552

對(duì)向量x和y進(jìn)行計(jì)算,并以向量t為索引進(jìn)行分組,求和。

> set.seed(1) # 定義x,y向量 > x<-y<-1:10;x;y [1] 1 2 3 4 5 6 7 8 9 10 [1] 1 2 3 4 5 6 7 8 9 10 # 設(shè)置分組索引t > t<-round(runif(10,1,100)%%2);t [1] 1 2 2 1 1 2 1 0 1 1 # 對(duì)x進(jìn)行分組求和 > tapply(x,t,sum) 0 1 2 8 36 11

由于tapply只接收一個(gè)向量參考,通過(guò)’…’可以把再傳給你FUN其他的參數(shù),那么我們想去y向量也進(jìn)行求和,把y作為tapply的第4個(gè)參數(shù)進(jìn)行計(jì)算。

> tapply(x,t,sum,y) 0 1 2 63 91 66

得到的結(jié)果并不符合我們的預(yù)期,結(jié)果不是把x和y對(duì)應(yīng)的t分組后求和,而是得到了其他的結(jié)果。第4個(gè)參數(shù)y傳入sum時(shí),并不是按照循環(huán)一個(gè)一個(gè)傳進(jìn)去的,而是每次傳了完整的向量數(shù)據(jù),那么再執(zhí)行sum時(shí)sum(y)=55,所以對(duì)于t=0時(shí),x=8 再加上y=55,最后計(jì)算結(jié)果為63。那么,我們?cè)谑褂谩魅肫渌膮?shù)的時(shí)候,一定要看清楚傳遞過(guò)程的描述,才不會(huì)出現(xiàn)的算法上的錯(cuò)誤。

8. rapply函數(shù)

rapply是一個(gè)遞歸版本的lapply,它只處理list類型數(shù)據(jù),對(duì)list的每個(gè)元素進(jìn)行遞歸遍歷,如果list包括子元素則繼續(xù)遍歷。

函數(shù)定義:

rapply(object, f, classes = "ANY", deflt = NULL, how = c("unlist", "replace", "list"), ...)

參數(shù)列表:

object:list數(shù)據(jù)

f: 自定義的調(diào)用函數(shù)

classes : 匹配類型, ANY為所有類型

deflt: 非匹配類型的默認(rèn)值

how: 3種操作方式,當(dāng)為replace時(shí),則用調(diào)用f后的結(jié)果替換原list中原來(lái)的元素;當(dāng)為list時(shí),新建一個(gè)list,類型匹配調(diào)用f函數(shù),不匹配賦值為deflt;當(dāng)為unlist時(shí),會(huì)執(zhí)行一次unlist(recursive = TRUE)的操作

…: 更多參數(shù),可選

比如,對(duì)一個(gè)list的數(shù)據(jù)進(jìn)行過(guò)濾,把所有數(shù)字型numeric的數(shù)據(jù)進(jìn)行從小到大的排序。

> x=list(a=12,b=1:4,c=c('b','a')) > y=pi > z=data.frame(a=rnorm(10),b=1:10) > a <- list(x=x,y=y,z=z) # 進(jìn)行排序,并替換原list的值 > rapply(a,sort, classes='numeric',how='replace') $x $x$a [1] 12 $x$b [1] 4 3 2 1 $x$c [1] "b" "a" $y [1] 3.141593 $z $z$a [1] -0.8356286 -0.8204684 -0.6264538 -0.3053884 0.1836433 0.3295078 [7] 0.4874291 0.5757814 0.7383247 1.5952808 $z$b [1] 10 9 8 7 6 5 4 3 2 1 > class(a$z$b) [1] "integer"

從結(jié)果發(fā)現(xiàn),只有$z$a的數(shù)據(jù)進(jìn)行了排序,檢查$z$b的類型,發(fā)現(xiàn)是integer,是不等于numeric的,所以沒(méi)有進(jìn)行排序。

接下來(lái),對(duì)字符串類型的數(shù)據(jù)進(jìn)行操作,把所有的字符串型加一個(gè)字符串’++++’,非字符串類型數(shù)據(jù)設(shè)置為NA。

> rapply(a,function(x) paste(x,'++++'),classes="character",deflt=NA, how = "list") $x $x$a [1] NA $x$b [1] NA $x$c [1] "b ++++" "a ++++" $y [1] NA $z $z$a [1] NA $z$b [1] NA

只有$x$c為字符串向量,都合并了一個(gè)新字符串。那么,有了rapply就可以對(duì)list類型的數(shù)據(jù)進(jìn)行方便的數(shù)據(jù)過(guò)濾了。

9. eapply函數(shù)

對(duì)一個(gè)環(huán)境空間中的所有變量進(jìn)行遍歷。如果我們有好的習(xí)慣,把自定義的變量都按一定的規(guī)則存儲(chǔ)到自定義的環(huán)境空間中,那么這個(gè)函數(shù)將會(huì)讓你的操作變得非常方便。當(dāng)然,可能很多人都不熟悉空間的操作,那么請(qǐng)參考文章 揭開(kāi)R語(yǔ)言中環(huán)境空間的神秘面紗,解密R語(yǔ)言函數(shù)的環(huán)境空間。

函數(shù)定義:

eapply(env, FUN, ..., all.names = FALSE, USE.NAMES = TRUE)

參數(shù)列表:

env: 環(huán)境空間

FUN: 自定義的調(diào)用函數(shù)

…: 更多參數(shù),可選

all.names: 匹配類型, ANY為所有類型

USE.NAMES: 如果X為字符串,TRUE設(shè)置字符串為數(shù)據(jù)名,F(xiàn)ALSE不設(shè)置

下面我們定義一個(gè)環(huán)境空間,然后對(duì)環(huán)境空間的變量進(jìn)行循環(huán)處理。

# 定義一個(gè)環(huán)境空間 > env # 向這個(gè)環(huán)境空間中存入3個(gè)變量 > env$a <- 1:10 > env$beta <- exp(-3:3) > env$logic <- c(TRUE, FALSE, FALSE, TRUE) > env # 查看env空間中的變量 > ls(env) [1] "a" "beta" "logic" # 查看env空間中的變量字符串結(jié)構(gòu) > ls.str(env) a : int [1:10] 1 2 3 4 5 6 7 8 9 10 beta : num [1:7] 0.0498 0.1353 0.3679 1 2.7183 ... logic : logi [1:4] TRUE FALSE FALSE TRUE

計(jì)算env環(huán)境空間中所有變量的均值。

> eapply(env, mean) $logic [1] 0.5 $beta [1] 4.535125 $a [1] 5.5

再計(jì)算中當(dāng)前環(huán)境空間中的所有變量的占用內(nèi)存大小。

# 查看當(dāng)前環(huán)境空間中的變量 > ls() [1] "a" "df" "env" "x" "y" "z" "X" # 查看所有變量的占用內(nèi)存大小 > eapply(environment(), object.size) $a 2056 bytes $df 1576 bytes $x 656 bytes $y 48 bytes $z 952 bytes $X 1088 bytes $env 56 bytes

eapply函數(shù)平時(shí)很難被用到,但對(duì)于R包開(kāi)發(fā)來(lái)說(shuō),環(huán)境空間的使用是必須要掌握的。特別是當(dāng)R要做為工業(yè)化的工具時(shí),對(duì)變量的精確控制和管理是非常必要的。

本文全面地介紹了,R語(yǔ)言中的數(shù)據(jù)循環(huán)處理的apply函數(shù)族,基本已經(jīng)可以應(yīng)對(duì)所有的循環(huán)處理的情況了。同時(shí),在apply一節(jié)中也比較了,3種數(shù)據(jù)處理方面的性能,R的內(nèi)置向量計(jì)算,要優(yōu)于apply循環(huán),大幅優(yōu)于for循環(huán)。那么我們?cè)谝院蟮腞的開(kāi)發(fā)和使用過(guò)程中,應(yīng)該更多地把a(bǔ)pply函數(shù)使用好。

忘掉程序員的思維,換成數(shù)據(jù)的思維,也許你就一下子開(kāi)朗了。


數(shù)據(jù)分析咨詢請(qǐng)掃描二維碼

若不方便掃碼,搜微信號(hào):CDAshujufenxi

數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機(jī)數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調(diào)用 initGeetest 進(jìn)行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調(diào),回調(diào)的第一個(gè)參數(shù)驗(yàn)證碼對(duì)象,之后可以使用它調(diào)用相應(yīng)的接口 initGeetest({ // 以下 4 個(gè)配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺(tái)檢測(cè)極驗(yàn)服務(wù)器是否宕機(jī) new_captcha: data.new_captcha, // 用于宕機(jī)時(shí)表示是新驗(yàn)證碼的宕機(jī) product: "float", // 產(chǎn)品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說(shuō)明請(qǐng)參見(jiàn):http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計(jì)時(shí)完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請(qǐng)輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請(qǐng)輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }