为什么我的代码在R中执行如此缓慢?
请,我有一个数据框,其中包含一个产品列表 对于每个产品,我都会进行外推以查找缺失的值(a列必须是介于1和20之间的列表) 然后,我还验证了,a中的某个值是否重复了很多次,因此我创建了一个新列来对其进行计数 最后,每个产品将只有一行,有20列b和20列每个类别的冗余计数 代码已启动并正在运行,但是执行时间太长了:为什么我的代码在R中执行如此缓慢?,r,R,请,我有一个数据框,其中包含一个产品列表 对于每个产品,我都会进行外推以查找缺失的值(a列必须是介于1和20之间的列表) 然后,我还验证了,a中的某个值是否重复了很多次,因此我创建了一个新列来对其进行计数 最后,每个产品将只有一行,有20列b和20列每个类别的冗余计数 代码已启动并正在运行,但是执行时间太长了: library(microbenchmark) library(dplyr) library(data.table) microbenchmark( "original" = {
library(microbenchmark)
library(dplyr)
library(data.table)
microbenchmark(
"original" = {
df_result <- data.frame()
prods<- dplyr::distinct(df,prod_id)$prod_id #Distinct Prod_ID
for(j in 1:NROW(prods)) {
dfj<- filter(df, prod_id==prods[j])
sdf<-as.data.frame(Hmisc::approxExtrap(dfj$a, dfj$b, xout = c(1:20))) #Extrapolating
sdf$z<-stack(pmax(table(factor(as.integer(dfj$a), levels = 1:20)), 1))[2:1]$values - 1 #Increment if a value was there more than 1 time
sdf<-select_(sdf,"y","z")
sdf<-as.data.frame(t(unlist(sdf)))
df_result<-rbind(df_result,sdf)
}
},
"new" = {
dt <- as.data.table(df)
do_stuff <- function(a, b) {
sdf <- Hmisc::approxExtrap(a, b, xout = c(1:20))
sdf$z <- stack(pmax(table(factor(as.integer(a), levels = 1:20)), 1))$values - 1
sdf <- as.data.frame(t(unlist(sdf[c("y", "z")])))
sdf
}
df_result <- dt[, do_stuff(a, b), by = prod_id]
}
)
类似数据:
a这是一个新的数据解决方案。表:
dt <- as.data.table(df)
do_stuff <- function(a, b) {
sdf <- Hmisc::approxExtrap(a, b, xout = c(1:20))
sdf$z <- stack(pmax(table(factor(as.integer(a), levels = 1:20)), 1))$values - 1
sdf <- as.data.frame(t(unlist(sdf[c("y", "z")])))
sdf
}
df_result <- dt[, do_stuff(a, b), by = prod_id]
您的整个示例在我(非常慢)的工作计算机上以11毫秒为基准。您正在使用的数据帧的大小是多少?我有数百万个产品,因此需要相当长的时间才能执行这应该返回什么dplyr::distinct(df,prod\u id)$prod\u id
?我认为这只是unique()
值我假设,do\u stuff()
函数中可能有更多优化的内容,但系数10只是一个开始。我试图在不使用data.table的情况下对此进行优化,但结果仍然是您的两倍。当我看到这个时,我删除了我的答案!
library(microbenchmark)
library(dplyr)
library(data.table)
microbenchmark(
"original" = {
df_result <- data.frame()
prods<- dplyr::distinct(df,prod_id)$prod_id #Distinct Prod_ID
for(j in 1:NROW(prods)) {
dfj<- filter(df, prod_id==prods[j])
sdf<-as.data.frame(Hmisc::approxExtrap(dfj$a, dfj$b, xout = c(1:20))) #Extrapolating
sdf$z<-stack(pmax(table(factor(as.integer(dfj$a), levels = 1:20)), 1))[2:1]$values - 1 #Increment if a value was there more than 1 time
sdf<-select_(sdf,"y","z")
sdf<-as.data.frame(t(unlist(sdf)))
df_result<-rbind(df_result,sdf)
}
},
"new" = {
dt <- as.data.table(df)
do_stuff <- function(a, b) {
sdf <- Hmisc::approxExtrap(a, b, xout = c(1:20))
sdf$z <- stack(pmax(table(factor(as.integer(a), levels = 1:20)), 1))$values - 1
sdf <- as.data.frame(t(unlist(sdf[c("y", "z")])))
sdf
}
df_result <- dt[, do_stuff(a, b), by = prod_id]
}
)
Unit: milliseconds
expr min lq mean median uq max neval
original 20.090200 20.841403 22.63290 21.705137 23.479769 32.535576 100
new 2.063369 2.279269 2.61532 2.411447 2.538806 9.312241 100