基于R中的观察类型有效地应用不同的功能

时间:2015-11-19 00:02:30

标签: r performance

假设我的数据集A至少包含"Type"列和"Data"列包含T种不同的观察类型,我会应用不同的函数:

funlist <- c(fun1, fun2,..., funT)

我可以通过以下方式实现这一目标:

方法1:sapply

for(t in 1:T){
    sapply(A[A[,"Type"]==t,"Data"],funlist[[t]])
}

方法2:mapply

funvector <- rep(NaN,length(A[,"Type"]))
for(t in 1:T){
    funvector[A[,"Type"]]==t] <- funlist[[t]]
}
mapply(function(fun, x) fun(x), funvector, A[,"Data"])

方法2特别不合需要,因为它创建了一个额外的对象,但在任何一种方法中我都无法避免创建for循环。由于我处理的数据集太大而内存约束是一个问题,是否有更有效的方法来编码这个问题,使内存使用最小化,即使以合理的速度成本?

3 个答案:

答案 0 :(得分:7)

其他几个选项:

基础R

A <- data.frame(Type=c(1,1,2,2), Data=c(0.5,1,100,101))
funlist <- list(exp, log)

by(A, A$Type, FUN=function(DF) funlist[[DF$Type[1]]](DF$Data) ) 
#A$Type: 1
#[1] 1.648721 2.718282
#----------------------------------------- 
#A$Type: 2
#[1] 4.605170 4.615121

dplyr

library(dplyr)
A %>% 
  group_by(Type) %>% 
  mutate(Data=funlist[[Type[1]]](Data))

Source: local data frame [4 x 2]
Groups: Type

#  Type     Data
#1    1 1.648721
#2    1 2.718282
#3    2 4.605170
#4    2 4.615121

data.table

library(data.table)
setDT(A)
A[, .(Data=funlist[[unlist(.BY)]](Data)), by=Type]

#   Type     Data
#1:    1 1.648721
#2:    1 2.718282
#3:    2 4.605170
#4:    2 4.615121

答案 1 :(得分:3)

您可以在需要应用时选择要应用的功能:

mapply(function(d,t) funlist[[t]](d), A$Data, A$Type)

答案 2 :(得分:1)

您可以调整第一种使用splitlapply的方法,这样可以避免for循环以及为每个唯一的#34; Type&#34;选择索引。

lapply(split(A, A[,"Type"]), function(Atype) 
       sapply(Atype[,"Data"],funlist[[Atype[1,"Type"]]]))