结果存储与嵌套(双)循环

时间:2017-08-29 13:30:02

标签: r

我有双循环(它在最后是三重循环,但当时只有一件事)。我需要将其结果保存到数据框中。我为单循环做这个没有问题,但是当我需要进行嵌套循环时我遇到了问题。我设法编写可复制的代码:

#first i create sample df with 3 random variables and index
df=data.frame("var1"=runif(18,min=0,max=1),`
              "var2"=runif(18,min=0,max=1),
              "var3"=runif(18,min=0,max=1),
              "index2"=c(rep(c("A","B","C"),6)),
              "index1"=c(rep(1,9),rep(2,9)))



#lists for subseting data in loops
list.1=list(1,2)
list.2=list("A","B","C")
#first loop based on list.2
for (i in 1:length(list.2)){
  i2=list.2[i]#indicator for inside loop to subset based on letter
  for (i in 1:length(list.1)){
        x=subset(df,df$index1 %in% list.1[i] & df$index2 %in% i2 )#subseting data 
        x=subset(x,select=c("var1","var2"))#second subset is not needed for example but it exists in my loop
        MyCalcs=data.frame(
          "INDEX1"=list.1[i],
          "CALC1"=mean(x$var1+x$var2),
          "CALC2"=mean(x$var1-x$var2),
          "CALC3"=mean(x$var1*x$var2)
        )#here I make some simple calculation 
        print(MyCalcs)#this i want put into data.frame
    }
}

对于使用do.call(rbind,list)的单循环效果很好,但在这种情况下,结果是print(MyCalcs)的最后2行。我也试过assign,但没有成功。

1 个答案:

答案 0 :(得分:1)

我会通过初始化数据集并向其添加行来解决此问题。这避免了使用rbind。我的方法在索引中容易出错,因此我将第二个循环的索引变量更改为与第一个循环中的索引变量不同的变量。

#first i create sample df with 3 random variables and index 
df=data.frame("var1"=runif(18,min=0,max=1),
          "var2"=runif(18,min=0,max=1),
          "var3"=runif(18,min=0,max=1),
          "index2"=c(rep(c("A","B","C"),6)),
          "index1"=c(rep(1,9),rep(2,9)))

 #lists for subseting data in loops
list.1=list(1,2)
list.2=list("A","B","C")
#here I initialize the dataset
MyCalcs.tot <- as.data.frame(matrix(rep(NA, length(list.1)*length(list.2)*4), ncol = 4))
names(MyCalcs.tot) <- c("INDEX1","CALC1", "CALC2", "CALC3")

#first loop based on list.2
for (i in 1:length(list.2)){
  i2=list.2[i]#indicator for inside loop to subset based on letter
  #your second loop used the same index as the first, 
  #this migth lead to confusion, thus i changed it to a j
  for (j in 1:length(list.1)){
    x=subset(df,df$index1 %in% list.1[j] & df$index2 %in% i2 )#subseting data 
    x=subset(x,select=c("var1","var2"))#second subset is not needed for example but it exists in my loop

    MyCalcs=data.frame(
      "INDEX1"=list.1[j],
      "CALC1"=mean(x$var1+x$var2),
      "CALC2"=mean(x$var1-x$var2),
      "CALC3"=mean(x$var1*x$var2)
    )#here I make some simple calculation 
    MyCalcs.tot[(i - 1)*length(list.1) + j,] <- MyCalcs #adding your calculations to the next row. 
    print(MyCalcs)#this i want put into data.frame
  }}

MyCalcs.tot是必需的数据框

你也可以完全避免使用循环并使用apply函数:

#first i create sample df with 3 random variables and index 
df=data.frame("var1"=runif(48,min=0,max=1),
              "var2"=runif(48,min=0,max=1),
              "var3"=runif(48,min=0,max=1),
              "index3"=c(rep(c("do","re","mi","fa"),12)),
              "index2"=c(rep(c("A","B","C"),16)),
              "index1"=c(rep(1,24),rep(2,24)))

comb <- as.data.frame(cbind(unlist(lapply(list.1,function(x)rep(x,length(list.2)*length(list.3)))),
              rep(unlist(lapply(list.2,function(x)rep(x,length(list.3)))),length(list.1)),
              rep(unlist(list.3),length(list.1)*length(list.2))))
names(comb) <- c("INDEX1","INDEX2","INDEX3")
comb$CALC1 <- apply(comb,1,function(x)mean(apply(df[,1:2],1,function(y)y[1]+ y[2])[which(df$index1 == x[1] & df$index2 == x[2] & df$index3 == x[3])]))
comb$CALC2 <- apply(comb,1,function(x)mean(apply(df[,1:2],1,function(y)y[1]- y[2])[which(df$index1 == x[1] & df$index2 == x[2] & df$index3 == x[3])]))
comb$CALC3 <- apply(comb,1,function(x)mean(apply(df[,1:2],1,function(y)y[1]* y[2])[which(df$index1 == x[1] & df$index2 == x[2] & df$index3 == x[3])]))