替换R中的for循环

时间:2014-04-11 18:42:31

标签: r for-loop

我正在尝试在编码时停止使用for循环,但是我有一个代表简单操作的问题。

让我们说我正在尝试对拥有多家餐馆的公司的数据集进行简单的最近邻估计。我有三个功能:城市,商店,月和一个目标功能销售。城市,商店和月份都用数字表示:城市取值在1-100之间,商店取值在1-50之间,月份在1-12之间。

现在,我想用apply函数替换这个for循环:

for (c in 1:100){
 for (s in 1:50){
  for (m in 1:12){
   dat1$Sales[dat1$City==c & dat1$Store==s & dat1$Month==m & is.na(dat1$Sales)] <-
    mean(dat1$Sales[dat1$City==c & dat1$Store==s & dat1$Month==m & !is.na(dat1$Sales)])
  }
 }
}

此应用函数的复杂性是什么?

非常感谢!

2 个答案:

答案 0 :(得分:3)

尝试使用aggregate。它有一个formula类似的界面,可以很容易地将函数的结果应用于data.frame的部分。然后只需将结果分配到需要它的dat1中的位置。

TempOut<- aggregate(Sales~City+Store+Month, FUN=mean,data=dat1)

dat1$Sales[is.na(dat1$Sales),]<-TempOut[TempOut$City==[dat1[is.na(dat1$Sales),]$City 
& TempOut$Store==[dat1[is.na(dat1$Sales),]$Store & TempOut$Month==
[dat1[is.na(dat1$Sales),]$Month,]$Sales

您可以将TempOut的创建和dat1$Sales的分配合并为一行,但这样会更难以阅读。我没有你的数据,所以我无法测试这个 - 但这应该让你走上正轨,即使那里有一个错字。

答案 1 :(得分:3)

这是一种data.table方式:

require(data.table)
setDT(dat1)

dat1[, Sales:={
  m=mean(Sales,na.rm=TRUE)
  replace(Sales, is.na(Sales), m)
},by=.(City, Store, Month)]

拥有像Sales[is.na(Sales)]:=...这样的东西会很不错,但现在这只是feature request。这是a similar question