【问题标题】:Avoiding for loops while subsetting and plotting in r在 r 中设置子集和绘图时避免 for 循环
【发布时间】:2016-09-21 04:36:56
【问题描述】:

避免下面使用的 for 循环的最佳方法是什么?它们循环遍历“状态”,使用它们对数据进行子集化以进行绘图和标记标题。也许apply 函数适用于用户定义的函数,但我不确定它会避免 for 循环。

# Attach packages
library(ggplot2)
library(dplyr)
library(gridExtra)

# Create data
set.seed(123)
states <- c("s1","s2","s3")
d <- data.frame(Year = sample(2010:2016, 1000, replace=T), 
           Month = sample(1:12, 1000, replace=T), 
           DepartureState = sample(states, 1000, replace=T), 
           DestinationState = sample(states, 1000, replace=T), 
           Price = sample(5000:8000, 1000, replace=T), 
           Cost = sample(2000:3000, 1000, replace=T))

# Apply grouping
dg <- d %>%
  group_by( Year, Month, DepState = DepartureState, DestState = DestinationState ) %>% 
  summarise( sumPrice = sum(Price), sumCost = sum(Cost), diff = sumPrice-sumCost, vol = n() )

# Add date column
dg$date <- as.POSIXct(paste(dg$Year, dg$Month, "01", sep = "-"))      

# Do things, e.g. subset and plot, for each combination of DepState-DestState pairs
for ( depState in states ) { 
  for ( destState in states ) {
    dgcut <- dg[dg$DepState == depState & dg$DestState == destState, ]

    description <- paste0(depState," to ", destState)
    plotname <- paste0(depState,"_",destState)
    #png(filename=paste0(plotname,".png"))
    p1 <- ggplot(dgcut, aes(x=date, y=sumPrice)) + geom_line() 
    p2 <- ggplot(dgcut, aes(x=date, y=sumCost)) + geom_line()
    p3 <- ggplot(dgcut, aes(x=date, y=diff)) + geom_line()
    p4 <- ggplot(dgcut, aes(x=date, y=vol)) + geom_line()
    grid.arrange(p1,p2,p3,p4,ncol=1,top = description) # from gridExtra
    #dev.off()
  }
}

注意,我只是想避免 for 循环,因为我知道在像 R 这样的矢量化语言中这被认为是不好的做法(或次优)。如果这种情况不是这样,请告诉我!

【问题讨论】:

    标签: r for-loop plot ggplot2 dplyr


    【解决方案1】:

    链接lapply 而不是for 循环?

    doThings <- function(depState,destState) {
        dgcut <- dg[dg$DepState == depState & dg$DestState == destState, ]
    
        description <- paste0(depState," to ", destState)
        plotname <- paste0(depState,"_",destState)
        #png(filename=paste0(plotname,".png"))
        p1 <- ggplot(dgcut, aes(x=date, y=sumPrice)) + geom_line() 
        p2 <- ggplot(dgcut, aes(x=date, y=sumCost)) + geom_line()
        p3 <- ggplot(dgcut, aes(x=date, y=diff)) + geom_line()
        p4 <- ggplot(dgcut, aes(x=date, y=vol)) + geom_line()
        grid.arrange(p1,p2,p3,p4,ncol=1,top = description) # from gridExtra
        #dev.off()
    }
    
    lapply(states,function(x) lapply(states,doThings,destState = x))
    

    【讨论】:

    • 酷,我没想到像这样嵌套apply。谢谢@shreyasgm!
    • 使用l_ply(包plyr)代替lapply将进一步加快进程。
    猜你喜欢
    • 1970-01-01
    • 2018-01-08
    • 1970-01-01
    • 1970-01-01
    • 2021-08-19
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多