獲取更好閱讀體驗: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):這是一個邏輯值,用于指定累積計算的方向。如果right為FALSE(默認(rèn)值),則Reduce()函數(shù)從左到右按順序處理序列中的元素。accumulate(可選,默認(rèn)為FALSE):這也是一個邏輯值,用于指定是否返回中間累積結(jié)果的向量。如果accumulate為FALSE(默認(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)注【生信擺渡】!