Home > database >  R: For loop is using only the last index
R: For loop is using only the last index

Time:08-04

Let's say that I am working with the following data.

library(tidyverse)

df_temp<-iris%>%
  select(!Species)

leng=2

for (j in 1:leng) {

  df<-data.frame(matrix(NA, nrow = dim(df_temp)[1], ncol=leng))
  #df<-array(NA, dim=c(dim(df_temp)[1], leng, 1))
  df[,j]<-df_temp[,j] / df_temp[, (j   leng) ]

}

when I run the for loop only the last index is shown. I have tried to use the ´df´ as array, but I have the same problem. The only solution that I found was define the columns at the beginning.

df<-tibble(
c1= rep(NA, nrow(df_temp)),
c2= rep(NA, nrow(df_temp))
)

  for (j in 1:leng) {

     df[,j]<-df_temp[,j] / df_temp[, (j   leng) ]

}

The problem is that in my original df I have 180 columns and I can not create manually all the columns.

CodePudding user response:

Instead of creating a data.frame object, create a NULL list and update inside the loop

df_list <- vector('list', leng)
names(df_list) <- paste0("c", seq_along(df_list))

for (j in 1:leng) {

     df_list[[j]]<-df_temp[,j] / df_temp[, (j   leng) ]

}

The list can be converted to a data.frame/tibble/matrix etc either using cbind with do.call (or just use bind_cols from dplyr i.e. dplyr::bind_cols(df_list)

out <- do.call(cbind.data.frame, df_list)

-output

> head(out)
        c1    c2
1 3.642857 17.50
2 3.500000 15.00
3 3.615385 16.00
4 3.066667 15.50
5 3.571429 18.00
6 3.176471  9.75

If the computation is as showed in the post, it can be easily done without a loop as well

head(df_temp[1:2]/df_temp[3:4])
  Sepal.Length Sepal.Width
1     3.642857       17.50
2     3.500000       15.00
3     3.615385       16.00
4     3.066667       15.50
5     3.571429       18.00
6     3.176471        9.75

CodePudding user response:

You are initializing a new df every time it loops. You can solve this easily in your current code by just moving the df argument outside the loop:

leng=2
df <- data.frame(matrix(NA, nrow = dim(df_temp)[1], ncol = leng)) #move outside the loop

for (j in 1:leng) {
  df[, j] <- df_temp[, j] / df_temp[, (j   leng)]
}

Output:

head(df)
#        X1    X2
#1 3.642857 17.50
#2 3.500000 15.00
#3 3.615385 16.00
#4 3.066667 15.50
#5 3.571429 18.00
#6 3.176471  9.75
  • Related