【R語言】apply函數族


R語言apply系列函數的基本作用是對數組(array,可以是多維)或者列表(list)按照元素或元素構成的子集合進行迭代,並將當前元素或子集合作為參數調用某個指定函數。vector是一維的array,dataframe可以看作特殊的list。

 

作用目標

在每個元素上應用

在子集合上應用

array

apply

tapply

list

lapply (…)

by

 

    其中 lapply(…) 為一族函數,包括簡化版: sapply,遞歸版: rapply。其中sapply又可分為可設置返回值模板vapply和多變量版mapply。另外vector比較特殊,vector是一維的array,但是卻不全是和array使用相同的函數。在按元素迭代的情況下,使用和list一樣的 lapply 函數;而在按子集合迭代的情況下, tapply 和 by 都能用,只是返回值形式不同。

 

1.    apply函數

在array上,沿margin方向,依次調用 FUN,返回結果通常為Array類型,如果返回值的向量長度不等,則返回List對象。margin表示數組引用的第幾維下標(即array[index1, index2, …]中的第幾個index),margin = 1表示行,2表示列,c(1,2) 表示行和列。

–       舉例1:

# 二維矩陣對象

x <- cbind(x1 = 3, x2 = c(4:1, 2:5))

dimnames(x)[[1]] <- letters[1:8]

apply(x, 2, mean, trim = .2)

apply(x, 1, mean, trim = .2)

apply(x, 2, sort)

 

–       舉例2:

#三維數組對象,數據向量中的值被賦給數組中的值時,將遵循“主列順序”,即第一個下標變化最快,最后的下表變化最慢。

z <- array(1:24, dim = 2:4)

apply(z, 3, mean)

apply(z, 1:2, function(x) seq_len(max(x)))

apply(z, 3, function(x) seq_len(max(x)))

 

注: 雖然vector是一維的array,但是不能使用apply,array只能用在二維及以上的array上,因為apply要求dim(X)的值必需是正數,vector對象的dim值為NULL。

 

2.    tapply函數

        按 indices 中的值分組,把相同值對應下標的array中的元素形成一個集合,應用到 FUN 。類似於group by indices的操作。當simplify = TRUE(默認)時,如果 FUN 返回的是一個值, tapply 返回Array,空值用NULL表示;若 FUN 返回多個值, tapply 返回list,空值使用NA表示。當simplify = FALSE時,tapply 都返回list 對象。 Array或list的長度和 indices 中不同值的個數相等。

        當 FUN 為 NULL 的時候,返回一個長度和array中元素個數相等的vector,指示分組的結果,vector中相等的元素所對應的下標屬於同一組。例如,返回c(1, 2, 1, 3, 2), 表示根據傳入的 indices ,第1、3個元素作為一組,第2、5個元素作為一組,第4個元素作為一組。

–       舉例1:

#tapply應用於vector

height <- c(174, 165, 180, 171, 160)

sex<-c("F","F","M","F","M")

#返回vector

tapply(height, sex, mean)

#返回list

tapply(height, sex, mean, simplify = F)

#因為函數fivenum返回多值,即使simplify = TRUE,也是返回list對象

tapply(height, sex, fivenum)

 

–       舉例2:

#tapply應用於matrix

m <- matrix(c(1:10), nrow=2)

ind <- matrix(c(rep(1,5),rep(2,5)), nrow=2)

tapply(height, sex)

tapply(m, ind, mean)

tapply(m, ind, fivenum)

 

–       舉例3:

#tapply實現crosstable功能

df<-data.frame(year=kronecker(2001:2003,rep(1,4)),loc=c('beijing','beijing','shanghai','shanghai'), type=rep(c('A','B'),6), sale=rep(1:12))

#以年份為行、地區為列計算銷售總量

tapply(df$sale, df[,c(‘year’,’loc’)], sum)

#以年份為行,類別為列計算銷售總量

tapply(df$sale, df[,c(‘year’,’type’)], sum)

#以年份,地區和類別計算銷售總量

tapply(df$sale, df[,c(‘year’,’loc’,’type’)],sum)

 

3.    lapply函數

在 list 上逐個元素調用 FUN 。可以用於dataframe上,因為dataframe是一種特殊形式的list。若對象不是list和表達式類型,會先強制轉換為list后再應用於FUN函數。

–       舉例1:

#lapply應用於matrix

lst <- list(a=c(1:5), b=c(6:10))

lapply(lst, mean)

 

–       舉例2:

# 非List會先強制轉換為List后再求均值,這時每一個元素都是一個list的對象

x <- 1:3

lapply(x, mean)

 

–       舉例3:

# 對dataframe使用lapply

df <- data.frame(x=c(1:3),y=c(6:8))

lapply(df, mean)

 

4.    sapply函數

      比 lapply 多了一個 simplify 參數。如果 simplify=FALSE ,則等價於lapply 。否則,在上一種情況的基礎上,將 lapply 輸出的list簡化為vector或matrix,默認的simplify=TRUE。

–       舉例1:

x<-list(a= 1:10, beta = exp(-3:3), logic = c(TRUE,FALSE,FALSE,TRUE))

#simplify = FALSE,同lapply 返回list對象

sapply(x, mean, simplify = FALSE, USE.NAMES = FALSE)

 

–       舉例2:

#simplify = TRUE,以向量形式返回結果

sapply(x, mean, simplify = TRUE, USE.NAMES = FALSE)

 

–       舉例3:

#默認的simplify=TRUE,fivenum返回多值,因此最終返回結果為matrix對象

sapply(x, fivenum)

 

5.    vapply函數

      vapply 類似於 sapply (但返回類型只包含Array) ,但是提供了第三個參數 FUN.VALUE 用以指明返回值的形式,可以看作返回值的模板。vapply會檢測FUN的所有值是否與FUN.VALUE兼容,以使他們具有相同的長度和類型,為了實現類型的兼容,類型存在被強制轉換為更高類型的可能,轉換順序:

 logical < integer < double < complex

–       舉例1:

#返回值的類型和長度要和預設值一致

x<-list(a= 1:10, beta = exp(-3:3), logic =c(TRUE,FALSE,FALSE,TRUE))

vapply(x, function(x) {c(mean(x),sd(x))}, FUN.VALUE = c(0, 0), USE.NAMES = TRUE)

 

6.    mapply函數

      mapply 是多變量版的 sapply(返回類型只包含Array) ,參數(…)部分可以接收多個數據, mapply 將FUN 應用於這些數據的第一個元素組成的數組,然后是第二個元素組成的數組,以此類推,直到用於每個參數的元素,要求多個數據的長度相同,或者是整數倍關系,如果參數長度不同,長度短的參數會被循環使用。返回值是array或list(如果返回值的向量長度不等,則返回List對象),取決於 FUN 返回值是一個還是多個。

–       舉例1:

#對兩個list對象的元素依次求和

mapply(sum, list(a=1,b=2,c=3), list(a=10,b=20,d=30))

 

–       舉例2:

#對第一和第二個對象使用rep函數,對象二長度較短會被循環使用

#返回對象長度不同,返回list對象

mapply(rep, c(1,2,4,5), c(3,4))

#返回對象長度相同同,返回matrix對象

mapply(rep, c(1,2,4,5), c(3,4)) 

 

–       舉例3:

#函數返回多值,因此返回matrix對象

mapply(function(x,y) c(x+y, x^y), c(1:5), c(1:5))

 

–       舉例4:

#使用MoreArgs給出rep的參數x值

mapply(rep, times = 1:2, MoreArgs = list(x = 42))

 

7.    rapply函數

 

  •       rapply 是遞歸版的 lappy 。基本原理是對list作遍歷,如果其中有的元素仍然是list,則繼續遍歷;對於每個非list類型的元素,如果其類型是 classes 參數指定的類型之一,則調用 FUN 。classes="ANY"表示匹配所有類型。how參數用來指定操作方式,有三種:"replace"對元素類型在 classes 中的直接用調用 FUN,不在的保留原始值。
  •  "list" 新建一個list,元素類型在 classes 中的,調用 FUN ;不在 classes 中的類型,使用 deflt 。會保留原始list的結構。
  • "unlist" 相當於對"list"模式下的結果調用 unlist(recursive=TRUE)

 

–       舉例1:

X <- list(list(a = pi, b =list(c = 2)), d = "a test")

#對X中的numeric類型的元素使用sqrt函數,保留非numeric元素值不變

rapply(X, sqrt, classes = "numeric", how ="replace")

 

–       舉例2:

#對X中的character類型的元素使用nchar函數,保留非nchar元素值不變

rapply(X, nchar, classes = "character", how ="replace")

 

–       舉例3:

#對X中的character類型的元素使用nchar函數,非character元素使用默認值deflt

rapply(X, nchar, classes = "character", deflt =as.integer(NA), how = "list")

 

–       舉例4:

#對X中的character類型的元素使用nchar函數,非character元素使用默認值deflt,返回結果使用unlist函數

rapply(X, nchar, classes = "character", deflt =as.integer(NA), how = "unlist")

 

–       舉例5:

#對X中的character類型的元素使用nchar函數,沒有設置deflt參數會直接舍棄非character元素,返回結果使用unlist函數

rapply(X, nchar, classes = "character", how ="unlist")

#對於how=list的情況,沒有設置deflt參數會使用默認值NULL

rapply(X, nchar, classes = "character", how = "list")

 

–       舉例6:

#對X中的numeric類型的元素使用log函數,函數參數為base=2

rapply(X, log, classes = "numeric", how ="replace", base = 2)

 

8.    eapply函數

對environment中命名值進行FUN計算后返回一個列表值,用戶可以請求所有使用過的命名對象。

–       舉例1:

env <- new.env(hash = FALSE)

env$a <- 1:10

env$beta <- exp(-3:3)

env$logic <- c(TRUE, FALSE, FALSE, TRUE)

# 列出環境中的對象

utils::ls.str(env)

# 對每個元素計算均值

eapply(env, mean)

詳細總結見下表:

 

函數

用法

輸入

輸出

語法

apply

對陣列行或者列使用函數

Array

Array/List

apply(X, MARGIN, FUN, …)

lapply

對列表或者向量使用函數

List/expression

List

lapply(X, FUN, …)

sapply

對列表或者向量使用函數

List/expression

List/Array

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

vapply

對列表或者向量使用函數

List/expression

Array

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

tapply

對不規則陣列使用函數

Array

Array/List

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

eapply

對環境中的值使用函數

Values in an Environment

List

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

mapply

對多個列表或者向量參數使用函數

List/Array

List/Array

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

rapply

運用函數遞歸產生列表

List

List/Vector

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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM