R 語言 apply 族函數基本用法(一)

2021-02-20 車錦森

R 語言有很多強大的循環函數,與其他程式語言(比如 Java、C/C++、Python、Julia 等)手寫循環不同,R 使用內置的循環函數會讓你的代碼更具有可讀性、更簡潔。下面介紹 7 種 apply 族循環函數和 2 個其他循環函數,讓你在數據統計和建模時更有效率。

一、apply函數

函數用法:

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

函數前面接受 3 個參數,返回一個向量。其中第一個參數 X 是向量或者矩陣,第三個 FUN 是函數,這個apply函數就是把 X 傳遞給 FUN 函數進行循環計算。第二個參數 MARGIN 如果等於 1,那麼就按行進行計算,如果是 2,那麼就是按照列計算。

比如求一個矩陣的所有行的和,運行下面代碼要先安裝 matlab 包,第一行進行包加載,第 17 行用包中的 magic 函數生成一個魔方矩陣:

> library(matlab)
載入程輯包:『matlab』
The following object is masked from 『package:stats』:
reshape
The following objects are masked from 『package:utils』:
find, fix
The following object is masked from 『package:base』:
sum
> (m <- magic(5)) [,1] [,2] [,3] [,4] [,5][1,] 17 24 1 8 15[2,] 23 5 7 14 16[3,] 4 6 13 20 22[4,] 10 12 19 21 3[5,] 11 18 25 2 9

我們可以用 R 的 rowSums 加總每一行:

> rowSums(m)[1] 65 65 65 65 65

每一行之和是 65,下面用 apply 函數進行計算,第二個參數為 1:

> apply(m, 1, sum)[1] 65 65 65 65 65

計算的結果跟上面一樣,當然這個例子體現不出 apply 的優勢。假如要對矩陣的每一行都轉化為字符串,那麼就可以用 apply 函數進行計算而不用手寫循環了:

> apply(m, 1, toString)[1] "17, 24, 1, 8, 15"  "23, 5, 7, 14, 16"  "4, 6, 13, 20, 22"  "10, 12, 19, 21, 3" "11, 18, 25, 2, 9" 

以上是 apply 函數的基本用法,第一個參數 X 也可以是數據框,第三個參數可以是你自己定義的函數。

ps:魔方矩陣的列加總:

> apply(m, 2, sum)[1] 65 65 65 65 65

列的和跟行的和是一樣的。

二、lapply函數

函數用法:

函數前面接受兩個參數,並返回一個列表。X 可以是一個向量或者矩陣等,FUN 是一個函數,作用於 X 的每一個元素上。

比如有下面一個列表:

> num <- list(a = c(2, 3, 3, 4), b = c(3, 4, 4, 5), c = 2, d = c(1, 2, 3), e = 2)> num$a[1] 2 3 3 4
$b[1] 3 4 4 5
$c[1] 2
$d[1] 1 2 3
$e[1] 2

如果想要去除列表中,每個元素的重複值(只保留一個,比如 2, 2, 2,只保留一個2),用手寫循環的方式比較麻煩的,這時就可以用到 lapply 函數:

> lapply(num, unique)$a[1] 2 3 4
$b[1] 3 4 5
$c[1] 2
$d[1] 1 2 3
$e[1] 2

用 unique 函數作用於列表中的每一個元素上,得到列表中每個元素中的值都是唯一的,達到去重的目的。

當然,這只是 lapply 函數一個很簡單的用法,實際開發時,你可以定義自己的 FUN 函數,可以開發出很複雜的算法。不過,總的來說 lapply 函數對用戶還是比較友好的。

三、vapply 函數

函數用法:

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

該函數跟前面的 lapply 函數一樣,FUN 作用於 X 中每一個元素。它最大的特點就是返回一個簡化版的列表或向量,並且,它需要第三個參數 FUN.VALUE 來指定返回值的模板。

比如上面例子的列表中計算每一個元素的長度:

> num$a[1] 2 3 3 4
$b[1] 3 4 4 5
$c[1] 2
$d[1] 1 2 3
$e[1] 2
> vapply(num, length, numeric(1))a b c d e 4 4 1 3 1

或者把前面的魔方矩陣 m 的每一個元素進行開方,然後以簡化的向量或數組輸出:

> m[,1] [,2] [,3] [,4] [,5][1,]   17   24    1    8   15[2,]   23    5    7   14   16[3,]    4    6   13   20   22[4,]   10   12   19   21    3[5,]   11   18   25    2    9> vapply(m, sqrt, numeric(1))[1] 4.123106 4.795832 2.000000 3.162278 3.316625 4.898979 2.236068 2.449490 3.464102 4.242641 1.000000 2.645751 3.605551[14] 4.358899 5.000000 2.828427 3.741657 4.472136 4.582576 1.414214 3.872983 4.000000 4.690416 1.732051 3.000000

可以看出,vapply 函數沒有前面那兩個函數那麼靈活,但是它在某些情況下還是比較有用的,比如我想操作某個數據結構中的每個元素,但又不想在保留原有數據結構,而只是想把操作有的數據進行原始的列表或向量輸出,那麼 vapply 函數就可以派上用場了。

四、sapply 函數

函數用法:

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

sapply 函數是介於 lapply 函數和 vapply 函數之間的一個簡化(simplfy),就是如果你既想作用於每一個函數,又不想硬性指定返回值的模板,又想要一個簡化的結果,那麼 sapply 函數就可以滿足你的要求了。現在可以用前面的例子換 sapply 函數計算一下:

> sapply(num, length)a b c d e4 4 1 3 1 > sapply(m, sqrt)[1] 4.123106 4.795832 2.000000 3.162278 3.316625 4.898979 2.236068 2.449490 3.464102 4.242641 1.000000 2.645751 3.605551[14] 4.358899 5.000000 2.828427 3.741657 4.472136 4.582576 1.414214 3.872983 4.000000 4.690416 1.732051 3.000000

由此可見,sapply 函數還是很方便的,它不用過多指定參數,但會儘可能的簡化結果並輸出來。這函數使用頻率還是比其他同族函數要高的。

下篇預告:mapply、tapply、rapply

相關焦點

  • R語言向量化運算:apply函數族用法心得
    R語言和Python的忠實擁躉,為成為一名未來的數據科學家而奮鬥終生。個人公眾號:數據科學家養成記 (微信ID:louwill12)當初入坑R語言的時候,就在各種場合看到老司機的忠告,「儘量避免使用循環!」一開始並不明白這其中的奧義,直到後來對R語言有深入接觸後,才領會R語言在向量化運算方面的強大功能。本篇內容就總結小編在使用R語言向量化運算apply函數族的一些心得體會。
  • 【R知識】R語言apply函數族筆記
    為什麼用apply因為我是一個程式設計師,所以在最初學習R的時候,當成「又一門程式語言」來學習,但是怎麼學都覺得彆扭。
  • 乾貨 掌握R語言中的apply函數族
    原因在於R的循環操作for和while,都是基於R語言本身來實現的,而向量操作是基於底層的C語言函數實現的,從性能上來看,就會有比較明顯的差距了。那麼如何使用C的函數來實現向量計算呢,就是要用到apply的家族函數,包括apply, sapply, tapply, mapply, lapply, rapply, vapply, eapply等。
  • R語言中的apply函數族
    前言apply函數族是R語言中數據處理的一組核心函數,通過使用apply函數,我們可以實現對數據的循環、分組、過濾、類型控制等操作
  • R語言apply家族函數的用法及其比較
    本文我們主要介紹如何使用R語言中的apply家族函數來實現向量化運算。案例中需要用到的數據集為了更好的理解apply家族函數的用法,本文需要用到mtcars數據集和beavers數據集。#mtcars數據集是從1974年 Motor Trend Us 雜誌採集到的,數據集的列由油耗以及汽車設計的10個方面共計11個變量組成,共有32條記錄。
  • R語言中plyr包
    文章轉載自哈爾濱商業大學銀河統計工作室前言  apply族函數是R語言中很有特色的一類函數,包括了apply、sapply、lapply、tapply
  • 使用apply族函數進行向量化運算替代for循環
    R基礎包base的apply族函數採用向量化運算實現批量計算,相較於for循環語句其代碼更加簡潔、運行速度也更快,恰當地運用這些函數能夠極大提高代碼質量。本篇主要介紹apply族函數的apply(),lapply(),sapply(),mapply()和tapply()函數。
  • 【R函數學習】R語言 apply函數家族詳解
    applyApply Functions Over Array Margins對陣列行或者列使用函數apply
  • R語言 apply函數家族詳解
    來自Conda的新浪博客apply {base}通過對數組或者矩陣的一個維度使用函數生成值得列表或者數組
  • Pandas數據處理|apply()函數的常規用法
    本文介紹一下關於 Pandas 中 apply() 函數的幾個常見用法,apply() 函數的自由度較高,可以直接對 Series 或者 DataFrame 中元素進行逐元素遍歷操作,方便且高效,具有類似於 Numpy 的特性。
  • 如何高效運行R語言
    本文主要討論如何提高R語言運行效率。資料來源於《Efficient R programming》,結合本人實踐,對其中的內容作了概要,提取了有用的部分。之前也多次介紹個如何提高R語言運行速度,本文系統全面地對這一問題進行了討論。
  • R數據分析:apply()的各種變體你分清了嗎?
    apply函數可以看作是循環的替代方法,在R語言中,apply函數的變體有很多,好多時候同學搞不清到底該用apply呢,還是tapply呢還是sapply
  • 成為R語言高手:再談apply和for loop循環
    用過一段時間R的朋友估計對R語言的for loop循環和apply函數孰優孰劣問題都不會陌生,網絡上可以找到很多討論,知乎上類似的問題也不少,可以看到大多數的意見是不要用
  • 【R函數學習】R語言時間序列函數整理
    #arma模型library(fUnitRoots) #進行單位根檢驗library(FinTS) #調用其中的自回歸檢驗函數library(fGarch) #GARCH模型library(nlme) #調用其中的gls函數library(fArma) #進行擬合和檢驗【基本函數
  • Day7:R語言課程 (R語言進行數據可視化)
    雖然R語言也有「循環」,但有些函數更直接,例如apply()函數map()族和函數族。map()族比apply()更直觀,因此主要學習map()。想學更多更多內容,可以使用apply()函數的資料(https://hbctraining.github.io/Intro-to-R/lessons/apply_functions.html)。2.
  • R點石成金三人組:apply,lapply,sapply
    首先,我們來看三人組的大哥:apply函數。apply函數是這三個函數的精髓,lapply是它的變種,sapply是lapply的精華簡潔版本。apply函數的基本命令格式是:apply(數據,向量,函數)。這個「數據、向量、函數」是什麼意思呢?
  • 一文弄懂apply、map和applymap三種函數的區別
    apply先從apply開始,當然最權威的說明還是要看官方文檔:apply是沿DataFrame的軸應用功能,傳遞給函數的對象是Series對象,其索引為DataFrame的索引(axis = 0'')或DataFrame的列(axis = 1'')當然最常用的還是
  • Pandas高級應用(map()與apply()函數)
    一.map()函數import pandas
  • apply家族
    ()函數是一個很R語言的函數,可以起到很好的替代冗餘的for循環的作用,R語言的循環操作for和while,都是基於R語言本身來實現的,而向量操作是基於底層的C語言函數實現的,所以使用apply()家族進行向量計算是高性價比的。
  • R語言從入門到精通:Day6-R語言數據操作進階及控制結構
    R中,概率函數形如 :[dpqr]distribution_abbreviation()其中第一個字母表示其所指分布的某一方面:d = 密度函數(density)p = 分布函數(distribution function)q = 分位數函數(quantile function)r = 生成隨機數(隨機偏差