如何在循环内使用2个输入优化r函数

时间:2018-03-27 22:00:53

标签: r

我是r的新手,我很惊讶运行我认为相当简单的代码行需要多长时间,这让我相信我错过了一些相当明显的东西。我已经在互联网上搜索并尝试了一些不同的函数迭代,但没有提高效率(按时间测量)。

Extract数据是一个18.5m行和11个变量的数据框。我正在尝试建立两件事,首先,住院时间超过7%的患者占所有患者的百分比,第二次21天住院的比例为7天。

LOS_prob_providerage <- function(x,y){ Var1 = which(Extract$LOS>=0 & Extract$ProviderCode == x & Extract$age_group == y) Var2 = which(Extract$LOS>=7 & Extract$ProviderCode == x & Extract$age_group == y) return(list(Strand=(sum(Extract$LOS[Var1] >= 7)/length(Var1))*100, ELOS=(sum(Extract$LOS[Var2] >= 21)/length(Var2))*100)) }

当我调用这个函数时,我给它一个医院列表作为x变量和一个年龄组来自y变量的列表(我似乎无法将它作为列表并输出所有医院的所有医院年龄组)使用以下代码集

Providerage_prob_strand = mapply(LOS_prob_providerage,Provider_unique, agelabels[1], SIMPLIFY = FALSE)

然后我使用2个列表创建一个数据框,该函数使用下面的代码输出

 National = data.frame(matrix(unlist(Providerage_prob_strand), ncol=2, 
 byrow=T),row.names = Provider_unique)
 colnames(National) <- c("Stranded_010","ELOS_010")

我随后为我的年龄组列表中的所有11个元素重新运行代码的最后部分,并附加到国家数据框。

问题1:使用r对循环进行编码的计算密集程度是否较低,或者由于r将所有内容存储在内存中的方式,循环只占用了这段时间?

问题2:是否可以使用mapply / sapply为x和y varibale提供r两个列表,并将结果输出到所有医院/年龄组的Strand和ELOS ?

1 个答案:

答案 0 :(得分:0)

我会使用data.table包。

要展示的一些虚拟数据(通常问题提供者提供这种做法通常是好的):

set.seed(123)
df1 = data.frame(
  provider = sample(LETTERS[1:4], 1000, T),
  los = round(runif(1000,0,40)),
  age_group = sample(1:4,1000, T))

现在我们将其转换为数据表

library(data.table)
setDT(df1)

我们可以像这样接触你想要的值:

providerlist = c('A','B')
age_list = c(1,2)

df1[provider %in% providerlist & age_group %in% age_list,
  .(los_greater_than7 = 100*sum(los>7)/.N),
  keyby = .(provider, age_group)]
#    provider age_group los_greater_than7
# 1:        A         1          92.40506
# 2:        A         2          81.81818
# 3:        B         1          77.27273
# 4:        B         2          87.50000

df1[provider %in% providerlist & age_group %in% age_list & los>7,
  .(los_greater_than20 = 100*sum(los>20)/.N),
  by = .(provider, age_group)]
#    provider age_group los_greater_than20
# 1:        A         1           56.16438
# 2:        A         2           66.66667
# 3:        B         1           56.86275
# 4:        B         2           58.92857