R语言-Reduce函数 让你的代码优美且强大

获取更好阅读体验:R语言-Reduce函数 让你的代码优美且强大

一、摘要

上篇推文介绍了如何快速对多个变量取交集:R语言-快速对多个变量取交集,最终用到了Reduce函数。

本文将专门介绍Reduce函数地绝妙之处,让你的代码简短而强大。

在R语言数据处理的过程中,我们经常需要对不同类型的数据进行聚合、累积或归约操作。Reduce函数是R语言中一个强大的工具,能够将一个序列的元素逐步减少为单个结果。本文将带您深入探索Reduce函数的技巧与窍门,助您在处理数字、字符、数据框、列表等不同类型的数据时事半功倍。

二、参数解释

在使用Reduce()函数时,我们需要了解以下关键参数的含义:

  • f:这是一个二元函数,用于指定如何将序列中的元素逐步减少为单个结果。函数f接受两个参数,第一个参数是前一个累积值,第二个参数是下一个元素。

  • x:这是一个序列,可以是向量、列表、矩阵、数据框或其他可迭代的数据结构。Reduce()函数将按顺序处理序列中的元素,并将每个元素传递给函数f进行累积计算。

  • init(可选):这是Reduce()函数的初始累积值。如果未提供init参数,则默认使用序列中的第一个元素作为初始累积值。

  • right(可选,默认为FALSE):这是一个逻辑值,用于指定累积计算的方向。如果rightFALSE(默认值),则Reduce()函数从左到右按顺序处理序列中的元素。

  • accumulate(可选,默认为FALSE):这也是一个逻辑值,用于指定是否返回中间累积结果的向量。如果accumulateFALSE(默认值),则Reduce()函数仅返回最终的累积结果。

三、使用示例

下面展示Reduce函数在实际数据处理中的用法,大家举一反三,观察其使用场景以灵活运用。

1. 多个变量取交集

就是上个推文介绍的:

# 生成10个数字集合
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. 多个数据框合并

for循环中,经常会遇到每个循环生成一个数据框,你可以先把每个循环的数据框保存在列表里,再使用Reduce进行合并。

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. 合并单细胞样本

# https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GSE146170
# 获取每个样本的细胞注释文件路径
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)))

# 获取每个样本的表达矩阵文件路径
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)

# 首列转为行名
umi_tb = col2rownames(umi_tb, remove = TRUE)

# 构建Seurat对象
loadp(Seurat)
obj = CreateSeuratObject(counts = umi_tb, meta.data = anno_tb)
obj

可以看到,结合lappy家族,代码更为简洁高效,因为后者输出的结果正可以作为前者的输入。

4. 处理单个数据框

  • 直接合并每个元素
tb = cars[1:5, ]
Reduce(c, tb)
# [1]  4  4  7  7  8  2 10  4 22 16
  • 其实unlist也可以,没想到吧,数据框其实也是列表,一种特殊的列表(使用typeof函数可以看出)
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函数是不是很优美和强大!


学习更多生信技巧,持续关注【生信摆渡】

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容