在R中正确使用“ClusterEval”?

6za6bjd0  于 2022-12-20  发布在  其他
关注(0)|答案(1)|浏览(127)

我正在使用R编程语言。
我有一个数据集,它记录了一组学生在不同时间的考试结果(1 =通过,0 =未通过):

library(data.table)
library(doParallel)

# Generate some sample data
id = sample.int(10000, 100000, replace = TRUE)
res = c(1,0)
results = sample(res, 100000, replace = TRUE)
date_exam_taken = sample(seq(as.Date('1999/01/01'), as.Date('2020/01/01'), by="day"), 100000, replace = TRUE)

# Create a data frame from the sample data
my_data = data.frame(id, results, date_exam_taken)
my_data <- my_data[order(my_data$id, my_data$date_exam_taken),]

# Generate some additional columns for each record
my_data$general_id = 1:nrow(my_data)
my_data$exam_number = ave(my_data$general_id, my_data$id, FUN = seq_along)
my_data$general_id = NULL

# Convert the data frame to a data.table
my_data = setDT(my_data)

# Create a cluster with 4 workers
cl = makeCluster(4)

我有这个函数,跟踪的次数每个学生失败的考试鉴于该学生未能通过前一次考试,通过考试鉴于该学生通过了前一次考试,通过考试鉴于该学生未能通过前一次考试和未能通过考试鉴于该学生通过了前一次考试。

my_function <- function(i) {
    # Use tryCatch to handle the case where there are no rows in the start_i data frame
    tryCatch({
        start_i = my_data[my_data$id == i,]
        pairs_i =  data.frame(first = head(start_i$results, -1), second = tail(start_i$results, -1))
        frame_i =  as.data.frame(table(pairs_i))
        frame_i$i = i
        return(frame_i)
    }, error = function(err) {
        # Return an empty data frame if there are no rows in the start_i data frame
        return(data.frame())
    })
}

现在,我想尝试对我的数据并行运行这个函数--也就是说,我想将属于不同学生的数据分配到我的计算机中的不同内核,以努力缩短执行这个函数所需的时间。

# Export the data frames and the my_function to the workers on the cluster
clusterExport(cl, c("my_data", "my_function", "data.table"))

# Assign each worker a different subset of the data to work on
clusterSetRNGStream(cl)
n = nrow(my_data)
chunks = rep(1:4, each = n / 4)
my_data = my_data[chunks == 1,]

# Evaluate the code on the cluster (final_out is the final result)
final_out = parLapply(cl, unique(my_data$id), my_function)

# alternate version
final_out = clusterApply(cl, unique(my_data$id), my_function)

# Stop the cluster when finished
stopCluster(cl)
    • 代码似乎运行无误-但我不确定是否所有操作都正确。**

有人能对此发表评论吗?
谢谢!

dldeef67

dldeef671#

据我所知,您所采用的方法达到了预期的效果。我怀疑集群是否比其他替代方法提供了任何真实的的速度改进。例如,如果您使用dplyr管道,您可以非常容易地做到这一点:

out <- my_data %>% 
  arrange(id, exam_number) %>% 
  group_by(id) %>% 
  mutate(prev_exam = lag(results)) %>% 
  group_by(id, results, prev_exam) %>% 
  tally() %>% 
  na.omit()

在我的机器macOS 12.6,3.6 GHz intel i9,128 GB RAM上,dplyr流水线比并行方法快3.5倍。正如@jblood94在评论中所说,大量的通信资源使得集群解决方案效率很低。也许有一个更好的数据表解决方案。

相关问题