R语言并行计算实战教程

foreach包增强了R循环遍历功能,并且提供了并行执行能力。本文通过示例带你轻松掌握这个高级技能。

foreach语法介绍

%do% 和 %dopar% 是对遍历对象执行一段业务功能代码的操作。

# 串行执行使用 --> %do%
output <- foreach(i = 'some object to iterate over', 'options') %do% {ex}

# 并行执行使用 --> %dopar%
output <- foreach(i = 'some object to iterate over', 'options') %dopar% {ex}

其中ex是表达式,在foreach循环环境中会被运行多次,%do%串行执行,%dopar%并行执行。
执行ex的结果默认作为list类型返回,我们通过.combine参数指定返回结果类型。c用于连接执行结果为向量类型,‘cbind’ 和 ‘rbind’ 合并向量为矩阵类型,‘+’ 和 ‘*’ 用于处理数值类型。

简单示例

# 求平方
# 等效于 square <- function(x) x^2; lapply(1:3, square)
foreach(i=1:3) %do%
  i^2

##多个参数

foreach(i=1:4, j=7:10) %do%
	sqrt(i*j)


# 等效于 colMeans(m)
# 生成3*3矩阵
m <- matrix(rnorm(9), 3, 3)
# c 生成向量
foreach(i=1:ncol(m), .combine=c) %do%
  mean(m[,i])
# 结果
# [1]  0.5745559 -0.1177918  1.4583174


并行执行

在执行并行计算之前,需要声明集群,即告诉R我们有多个核(cpu)。具体步骤如下:

  1. 加载包doParallel,增强foreach函数的功能
  2. 检测机器CPU核数,一般规则是至少保留一核执行其他任务。假设你是8核,则最多设置为7
  3. 声明集群,使用makeCluster(coreNum, type).

其中type可以为PSOCK、FORK,前者创建新的session,后者拷贝当前session;

  1. 使用registerDoParallel函数注册集群。
library(doParallel)
detectCores()
# 8

myCluster <- makeCluster(7, # number of cores to use
                         type = "FORK") # type of cluster
# 注册计算
registerDoParallel(myCluster)

data <- foreach(item = 1:10, .combine = 'c') %dopar% {
  item = item *2
}

data

综合示例实战

最后我们通过实际例子展示如何高效使用foreach函数。
某业务每天的记录保留在当天日期(yyyy-MM-dd)为文件夹的data.csv文件中,现在我们编写函数一次性读取一段时间内的所有记录并合并结果为数据框。

假设文件夹为sales,则其中内容为:
2022-01-01/data.csv
2022-01-02/data.csv

2022-06-09/data.csv

代码如下:

library(plyr)
library(foreach)

readCsvDates <- function(base.dir, date.from, date.to) {
  # 字符串转为日期
  date.from <- as.Date(date.from)
  date.to <- as.Date(date.to)
  # 生成日期序列
  dates <- seq.Date(date.from, date.to, by = "day")
  
  # 利用foreach读取文件,ldply组合结果为数据框
  x <- ldply(foreach(day = dates, combine = rbind) %do% {
    read.csv(sprintf("%s/%s/data.csv", base.dir, day),
             header = T,
             sep = "\t", stringsAsFactors = F)
  })
  x
}

## 定义readData函数
readSales <- function(date.from, date.to) {
  data <- readCsvDates("sales", date.from, date.to)
  data
}

# 执行文件加载,生成数据框
result <- readSales("2022-05-01", "2022-05-02")
head(result)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值