更快的For循环?

Bla*_*Hat 1 loops for-loop r

我有这段代码,我循环通过250,000项.以下是代码中的步骤:1.给定产品的子集数据2.将数据与月份数据帧合并(左).3.用该特定产品名称替换空产品名称4.将销售的NA值替换为0

以下是两个产品的示例数据集.数据:

data2 <- data.frame(product_no = c("A", "A", "A", "B","B","B"), 
                           sales = c(200, 130, 221, 310,109, 98), month = c(1, 4, 5, 8,1, 12), stringsAsFactors=FALSE)

month_unique <- as.data.frame(seq(1,12, by=1))
colnames(month_unique)[colnames(month_unique)=="seq(1, 12, by = 1)"] <- "month"
Run Code Online (Sandbox Code Playgroud)

码:

unique_product <- unique(data2$product_no)
data3 <- data.frame()

process_time <- Sys.time()
for (i in 1:length(unique_product)){
  step1 <- subset(data2, product_no==unique_product[i])
  step2 <- merge(month_unique,step1, by="month", all.x = TRUE)
  step2$product_no <- unique_product[i]
  step2[is.na(step2)] <- 0
  data3 <- rbind(data3, step2)
}
Sys.time() - process_time
Run Code Online (Sandbox Code Playgroud)

预期结果:

data3
Run Code Online (Sandbox Code Playgroud)

有更快的方法吗?

谢谢.

Dav*_*son 6

您可以expand.grid创建月份的所有组合product_no,然后将N替换为0.

library(tidyr)

combinations <- expand.grid(month = 1:12,
                            product_no = unique(data2$product_no),
                            stringsAsFactors = FALSE)

result <- merge(combinations, data2, all.x = TRUE)
result <- replace_na(result, list(sales = 0))
Run Code Online (Sandbox Code Playgroud)

请注意,我正在使用replace_natidyr包中的函数,但您也可以这样做

result$sales[is.na(result$sales)] <- 0
Run Code Online (Sandbox Code Playgroud)

您也可以left_join在dplyr中使用该功能,这通常比快merge.在dplyr函数中,通常(但不一定)链接在一起%>%:

library(dplyr)

result <- combinations %>%
    left_join(data2) %>%
    replace_na(list(sales = 0))
Run Code Online (Sandbox Code Playgroud)