R語言-Reduce函數(shù) 讓你的代碼優(yōu)美且強大

獲取更好閱讀體驗:R語言-Reduce函數(shù) 讓你的代碼優(yōu)美且強大。

一、摘要

上篇推文介紹了如何快速對多個變量取交集:R語言-快速對多個變量取交集,最終用到了Reduce函數(shù)。

本文將專門介紹Reduce函數(shù)地絕妙之處,讓你的代碼簡短而強大。

在R語言數(shù)據(jù)處理的過程中,我們經(jīng)常需要對不同類型的數(shù)據(jù)進(jìn)行聚合、累積或歸約操作。Reduce函數(shù)是R語言中一個強大的工具,能夠?qū)⒁粋€序列的元素逐步減少為單個結(jié)果。本文將帶您深入探索Reduce函數(shù)的技巧與竅門,助您在處理數(shù)字、字符、數(shù)據(jù)框、列表等不同類型的數(shù)據(jù)時事半功倍。

二、參數(shù)解釋

在使用Reduce()函數(shù)時,我們需要了解以下關(guān)鍵參數(shù)的含義:

  • f:這是一個二元函數(shù),用于指定如何將序列中的元素逐步減少為單個結(jié)果。函數(shù)f接受兩個參數(shù),第一個參數(shù)是前一個累積值,第二個參數(shù)是下一個元素。

  • x:這是一個序列,可以是向量、列表、矩陣、數(shù)據(jù)框或其他可迭代的數(shù)據(jù)結(jié)構(gòu)。Reduce()函數(shù)將按順序處理序列中的元素,并將每個元素傳遞給函數(shù)f進(jìn)行累積計算。

  • init(可選):這是Reduce()函數(shù)的初始累積值。如果未提供init參數(shù),則默認(rèn)使用序列中的第一個元素作為初始累積值。

  • right(可選,默認(rèn)為FALSE):這是一個邏輯值,用于指定累積計算的方向。如果rightFALSE(默認(rèn)值),則Reduce()函數(shù)從左到右按順序處理序列中的元素。

  • accumulate(可選,默認(rèn)為FALSE):這也是一個邏輯值,用于指定是否返回中間累積結(jié)果的向量。如果accumulateFALSE(默認(rèn)值),則Reduce()函數(shù)僅返回最終的累積結(jié)果。

三、使用示例

下面展示Reduce函數(shù)在實際數(shù)據(jù)處理中的用法,大家舉一反三,觀察其使用場景以靈活運用。

1. 多個變量取交集

就是上個推文介紹的:

# 生成10個數(shù)字集合
for(i in 1:10){
    var_name = paste0("var", i)
    set.seed(i)
    nums = sample(1:100, 80)
    assign(var_name, nums)
}

Reduce(intersect, lapply(paste0("var", 1:10), get))
# [1] 87 59 21 84 42 24 18 76 16

2. 多個數(shù)據(jù)框合并

for循環(huán)中,經(jīng)常會遇到每個循環(huán)生成一個數(shù)據(jù)框,你可以先把每個循環(huán)的數(shù)據(jù)框保存在列表里,再使用Reduce進(jìn)行合并。

resL = list()
for(i in 1:5){
    from = 1 + 10 * i
    to = from + 2
    resL[[i]] = iris[from:to, ]
}
resT = Reduce(rbind, resL)
#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
# 11          5.4         3.7          1.5         0.2     setosa
# 12          4.8         3.4          1.6         0.2     setosa
# 13          4.8         3.0          1.4         0.1     setosa
# 21          5.4         3.4          1.7         0.2     setosa
# 22          5.1         3.7          1.5         0.4     setosa
# 23          4.6         3.6          1.0         0.2     setosa
# 31          4.8         3.1          1.6         0.2     setosa
# 32          5.4         3.4          1.5         0.4     setosa
# 33          5.2         4.1          1.5         0.1     setosa
# 41          5.0         3.5          1.3         0.3     setosa
# 42          4.5         2.3          1.3         0.3     setosa
# 43          4.4         3.2          1.3         0.2     setosa
# 51          7.0         3.2          4.7         1.4 versicolor
# 52          6.4         3.2          4.5         1.5 versicolor
# 53          6.9         3.1          4.9         1.5 versicolor

3. 合并單細(xì)胞樣本

# https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE146170
# 獲取每個樣本的細(xì)胞注釋文件路徑
anno_file = lf("rf", "00_raw/anno")

# lapply批量讀取, 并使用Reduce合并
anno_tb = Reduce(rbind, lapply(anno_file, function(x) data.table::fread(x, data.table = FALSE)))

# 獲取每個樣本的表達(dá)矩陣文件路徑
umi_file = lf("rf", "00_raw/UMI")

# lapply批量讀取
umi_list = lapply(umi_file, function(x) data.table::fread(x, data.table = FALSE))

# 使用Reduce合并
umi_tb = Reduce(function(df1, df2) merge(df1, df2, by = "gene_name", all = TRUE), umi_list)

# 首列轉(zhuǎn)為行名
umi_tb = col2rownames(umi_tb, remove = TRUE)

# 構(gòu)建Seurat對象
loadp(Seurat)
obj = CreateSeuratObject(counts = umi_tb, meta.data = anno_tb)
obj

可以看到,結(jié)合lappy家族,代碼更為簡潔高效,因為后者輸出的結(jié)果正可以作為前者的輸入。

4. 處理單個數(shù)據(jù)框

  • 直接合并每個元素
tb = cars[1:5, ]
Reduce(c, tb)
# [1]  4  4  7  7  8  2 10  4 22 16
  • 其實unlist也可以,沒想到吧,數(shù)據(jù)框其實也是列表,一種特殊的列表(使用typeof函數(shù)可以看出)
unlist(tb)
# speed1 speed2 speed3 speed4 speed5  dist1  dist2  dist3  dist4  dist5 
#      4      4      7      7      8      2     10      4     22     1

5. 累加

  • 如何使用R語言計算1到100的和?
Reduce(`+`, 1:100)
# [1] 5050

例子是舉不完的,大家要靈活使用。

Reduce函數(shù)是不是很優(yōu)美和強大!


學(xué)習(xí)更多生信技巧,持續(xù)關(guān)注【生信擺渡】!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容