在R中以更好的方式编写for循环

时间:2018-12-04 09:16:24

标签: r dplyr

我正在寻找针对问题的优化解决方案,我确实有解决方案,但这需要时间。

有2个数据框:

Df1: 
Hid     MST     Date      Percent  year_1_back     Avg_Percent 
1        1    01-01-2018     .90    01-01-2017     0

DF1共有19,900条记录

DF2:
Hid     MST     Date      Percent  
1        1    01-01-2017     .90   
1        1    02-01-2017     .91

直到今天我都在DF2中保存数据

因此,现在,我想通过从DF2中获取1年的平均百分比数据来更新DF1中的Avg_Percent列。

现有逻辑:

for(row in 1:nrow(DF1)){
  #row = 1
  hid <- DF1[row,]$hid
  mst <- DF1[row,]$mst
  startdate <- DF1[row,]$year_1_back
  enddate <- DF1[row,]$Date
  test1 <- DF2[which(DF2$Date>= startdate & DF2$Date<= enddate & DF2$MarketSegmentType == mst & DF2$hid== hid),]
  AVG <- mean(test1$Percet)
  DF1[row,]$Avg_Percent <- AVG
}

这给了我结果,但是执行时间很长。我认为dplyr会很有用,但不知道如何使用该功能。

我正在寻找一些比现有代码更快的代码。

1 个答案:

答案 0 :(得分:2)

我们可以基于sqldf使用df1.Date >= df2.Date AND df1.year_1_back <= df2.Date进行JOIN,然后进行分组和总结。

library(dplyr)
library(sqldf)
sqldf::sqldf("SELECT a.Hid AS a_Hid, a.MST As a_MST, a.Date, a.year_1_back, b.Hid, b.MST, b.Percent, b.Date AS DF2DATE
FROM df1 a
JOIN df2 b on a.Hid = b.Hid AND a.MST = b.MST AND
a.Date >= b.Date AND a.year_1_back <= b.Date") %>% 
       as_tibble() %>% group_by(a_Hid, a_MST, Date, year_1_back) %>%
       summarise(Percent=mean(Percent, na.rm = TRUE))

# A tibble: 1 x 5
# Groups:   a_Hid, a_MST, Date [?]
     a_Hid a_MST Date       year_1_back Percent
     <int> <int> <date>     <date>        <dbl>
  1     1     1 2018-01-01 2017-01-01    0.905
相关问题