优化for循环以更快地运行

问题描述 投票:0回答:1

我正在使用超过300万个观测值的数据集。该数据集包含我感兴趣的超过770,000个唯一ID。该数据包括有关这些ID的描述性信息。挑战在于这些唯一的ID包含非唯一的重复项,这意味着我需要找到一种合并数据的方法。

经过深思熟虑,我决定为数据集中的每个ID采用每一列的模式。输出为我提供了每个ID每个列的最通用值。通过采用最常见的值,我能够将每个ID的非唯一重复项合并为一行。

问题:为此,我在for循环中遍历了770,000个唯一ID。我想使用尽可能高效的代码,因为我一直在使用for循环来完成几天。

鉴于我提供的代码,有没有一种方法可以优化代码,使用并行处理,或者通过其他方法更有效地完成任务?

可复制代码:

ID <- c(1,2,2,3,3,3)
x1 <- c("A", "B", "B","C", "C", "C")
x2 <- c("alpha", "bravo", "bravo", "charlie", "charlie2", "charlie2")
x3 <- c("apple", "banana", "banana", "plum1", "plum1", "plum")

df <- data.frame(ID, x1, x2, x3)

#Mode Function
getmode <- function(v) {
  uniqv <- unique(v)
  uniqv[which.max(tabulate(match(v, uniqv)))]
}

library(reshape2)

#Takes the mode for every column
mode_row <- function(dat){
  x <- setNames(as.data.frame(apply(dat, 2, getmode)), c("value"))
  x$variable <- rownames(x); rownames(x) <- NULL
  mode_row <- reshape2::dcast(x, . ~ variable, value.var = "value")
  mode_row$. <- NULL
  return(mode_row)
}

#Take the mode of each row to account for duplicate donors
df2 <- NULL
for(i in unique(df$ID)){
  df2 <- rbind(df2, mode_row(subset(df, ID == i)))
  #message(i)

}

df2

预期输出:

  ID x1       x2      x3
1  1  A    alpha   apple
2  2  B    bravo banana
3  3  C charlie2   plum1

r for-loop optimization parallel-processing apply
1个回答
1
投票

在R,dplyrdata.table中有可用的分组功能:

Base R:

aggregate(.~ID, df, getmode)

#  ID x1       x2      x3
#1  1  A    alpha   apple
#2  2  B    bravo  banana
#3  3  C charlie2   plum1

dplyr

library(dplyr)
df %>% group_by(ID) %>% summarise(across(x1:x3, getmode))
#Use summarise_at in older version of dplyr
#df %>% group_by(ID) %>% summarise_at(vars(x1:x3), getmode)

data.table

library(data.table)
setDT(df)[, lapply(.SD, getmode), ID, .SDcols = x1:x3]
© www.soinside.com 2019 - 2024. All rights reserved.