我正在处理超过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
答案 0 :(得分:1)
基本R,dplyr
和data.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]