为什么我的代码在R中执行如此缓慢?

为什么我的代码在R中执行如此缓慢?,r,R,请,我有一个数据框,其中包含一个产品列表 对于每个产品,我都会进行外推以查找缺失的值(a列必须是介于1和20之间的列表) 然后,我还验证了,a中的某个值是否重复了很多次,因此我创建了一个新列来对其进行计数 最后,每个产品将只有一行,有20列b和20列每个类别的冗余计数 代码已启动并正在运行,但是执行时间太长了: library(microbenchmark) library(dplyr) library(data.table) microbenchmark( "original" = {

请,我有一个数据框,其中包含一个产品列表

对于每个产品,我都会进行外推以查找缺失的值(a列必须是介于1和20之间的列表)

然后,我还验证了,a中的某个值是否重复了很多次,因此我创建了一个新列来对其进行计数

最后,每个产品将只有一行,有20列b和20列每个类别的冗余计数

代码已启动并正在运行,但是执行时间太长了:

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