代码之家  ›  专栏  ›  技术社区  ›  dnagirl

如何加速这个R代码

  •  8
  • dnagirl  · 技术社区  · 15 年前

    我有一个数据框( link to file )我用18列11520行进行如下转换:

    library(plyr)
    df.median<-ddply(data, .(groupname,starttime,fPhase,fCycle), 
                     numcolwise(median), na.rm=TRUE)
    

    根据system.time(),运行大约需要这么长时间:

       user  system elapsed 
       5.16    0.00    5.17
    

    6 回复  |  直到 15 年前
        1
  •  9
  •   Joshua Ulrich    15 年前

    只是使用 aggregate

    > groupVars <- c("groupname","starttime","fPhase","fCycle")
    > dataVars <- colnames(data)[ !(colnames(data) %in% c("location",groupVars)) ]
    > 
    > system.time(ag.median <- aggregate(data[,dataVars], data[,groupVars], median))
       user  system elapsed 
       1.89    0.00    1.89 
    > system.time(df.median <- ddply(data, .(groupname,starttime,fPhase,fCycle), numcolwise(median), na.rm=TRUE))
       user  system elapsed 
       5.06    0.00    5.06 
    > 
    > ag.median <- ag.median[ do.call(order, ag.median[,groupVars]), colnames(df.median)]
    > rownames(ag.median) <- 1:NROW(ag.median)
    > 
    > identical(ag.median, df.median)
    [1] TRUE
    
        2
  •  7
  •   Community Mohan Dere    8 年前

    总结一下评论中的一些观点:

    1. 在开始优化之前,您应该对“可接受”的性能有一些了解。根据所需的性能,可以更具体地说明如何改进代码。例如,在某个阈值处,您需要停止使用R并转到编译语言。
    2. search for [r] + rprof ).
    3. plyr 主要是为了易用性而不是性能而设计的(尽管最新版本有一些不错的性能改进)。一些基本函数更快,因为它们的开销更少。@JDLong指出 a nice thread 这涵盖了其中的一些问题,包括哈德利的一些专门技术。
        3
  •  4
  •   Richie Cotton Joris Meys    15 年前

    x <- 1:1e6
    y <- sample(x)
    system.time(for(i in 1:1e2) median(x))
       user  system elapsed 
       3.47    0.33    3.80
    
    system.time(for(i in 1:1e2) median(y))
       user  system elapsed 
       5.03    0.26    5.29
    

    对于新的数据集,在导入数据时按适当的列对数据进行排序。对于现有的数据集,您可以将它们排序为批处理作业(在web应用程序之外)。

        4
  •  3
  •   VitoshKa    15 年前

    为约书亚的解决方案添砖加瓦。如果决定使用平均值而不是中值,则可以将计算速度再提高4倍:

    > system.time(ag.median <- aggregate(data[,dataVars], data[,groupVars], median))
       user  system elapsed 
       3.472   0.020   3.615 
    > system.time(ag.mean <- aggregate(data[,dataVars], data[,groupVars], mean))
       user  system elapsed 
       0.936   0.008   1.006 
    
        5
  •  3
  •   Collin    12 年前

    library(dplyr)
    
    system.time({
      data %>% 
        group_by(groupname, starttime, fPhase, fCycle) %>%
        summarise_each(funs(median(., na.rm = TRUE)), inadist:larct)
    })
    #>    user  system elapsed 
    #>   0.391   0.004   0.395
    

    (你需要dplyr 0.2才能得到 %>% summarise_each

    相比之下,这对普利尔有利:

    library(plyr)
    system.time({
      df.median <- ddply(data, .(groupname, starttime, fPhase, fCycle), 
        numcolwise(median), na.rm = TRUE)
    })
    #>    user  system elapsed 
    #>   0.991   0.004   0.996
    

    以及 aggregate() (代码来自@joshua ulrich)

    groupVars <- c("groupname", "starttime", "fPhase", "fCycle")
    dataVars <- colnames(data)[ !(colnames(data) %in% c("location", groupVars))]
    system.time({
      ag.median <- aggregate(data[,dataVars], data[,groupVars], median)
    })
    #>    user  system elapsed 
    #>   0.532   0.005   0.537
    
        6
  •  2
  •   doug    15 年前

    > system.time(table(BB$year))
        user  system elapsed 
       0.007   0.002   0.009 
    
    > system.time(ddply(BB, .(year), 'nrow'))
        user  system elapsed 
       0.183   0.005   0.189 
    

    第二,我做到了 调查这是否会提高您的性能,但是对于您现在使用的大小和更大的数据帧,我使用 data.table

    dt1 = data.table(my_dataframe)