简体   繁体   中英

Altering output from nested for loop with a list in R

Edit Abstract: My problem here is that when I run a list of four data frames through a nested for loop (which works correctly and is doing what I need it to do) I can only get the output into three columns of a matrix when I would prefer to have a single column for each parameter of my inner for loop. I'm thinking that the loops are creating a column for each item on the list (please see output below) because when I try to store the output as just single columns I get this error: incorrect number of dimensions. The reason that I need the data in columns rather than storing it in a whole matrix that was created outside the loop is because in the future I will be running different files and will not know the amount of rows that will be generated by the loops. I really would appreciate help with this, I'm still finding it difficult to understand how to get certain outputs from loops, although believe me, it's not from lack of trying.

This may be a very easy problem to solve, but the answer has eluded me. I have nested for loops and my input is a list of four data frames (although this number could and will vary with different data sets). It is important that my input stay a list. So far I've created matrices to store these outputs, and the outputs end up going into three separate columns of the matrices, I'm assuming that's because it's one column for each item on the list (I know I said four items on the list, but the code only ends up making changes to three out of the four items on the list).

LAT <- matrix(data=NA, nrow=50, ncol=5) #Matrices to store the output in
LON <- matrix(data=NA, nrow=50, ncol=5) #but ideally these would be columns: LON <- c()
Impute <- matrix(data=NA, nrow=50, ncol=5)
ID <- matrix(data=NA, nrow=50, ncol=5)

for (i in 1:length(subM.List))   { #Looping through each submatrix in the list (i loops through each submatrix on list)
  for (j in 2:nrow(subM.List[[i]])) { #Loop through each row of each submatrix in the list (j loops through each row on each submatrix)
    if ((subM.List[[i]][j, "LAT"] == -180) & #if there is a -180 and a value greater than 0 in activityIN, break the inner for loop
      (subM.List[[i]][j-1, "ACTIVITYIN"] !=  0)) { #Will break if it find a -1, -2, 1, 2, 3, or 4.
  break
} 
else if ((subM.List[[i]][j, "LAT"] == -180) &
           (subM.List[[i]][j, "ACTIVITYIN"] ==  0)) {
  ID[j,i] <- (subM.List[[i]][j,"ID"]) #Imputation 1, imputing data points with 0 activity intensity and -180 for LON
  LAT[j,i] <- (subM.List[[i]][j,"LAT"] = subM.List[[i]][j-1,"LAT"])
  LON[j,i] <- (subM.List[[i]][j,"LON"] = subM.List[[i]][j-1,"LON"])
  Impute[j,i] <- (subM.List[[i]][j,"Impute"] = 1) #populates the impute column. If point has been imputed, row will have a 1 value
  ctr <- (ctr + 1)}
  }
}

loopOutput = cbind(LAT, LON, Impute, ID) #binding together the 4 columns of the loop output

The current output from the LON variable looks like this:

> LON
      [,1]      [,2]      [,3]      [,4]

 [1,]   NA        NA        NA        NA
 [2,]   NA        NA        NA        NA
 [3,]   NA        NA        NA        NA
 [4,]   NA        NA        NA        NA
 [5,]   NA        NA        NA        NA
 [6,]   NA        NA        NA        NA
 [7,]   NA        NA        NA        NA
 [8,]   NA        NA        NA        NA
 [9,]   NA        NA        NA        NA
[10,]   NA        NA        NA        NA
[11,]   NA        NA        NA        NA
[12,]   NA -117.2295 -117.2289 -117.2295
[13,]   NA -117.2295 -117.2289 -117.2295
[14,]   NA -117.2295 -117.2289 -117.2295
[15,]   NA        NA -117.2289 -117.2295
[16,]   NA        NA -117.2289 -117.2295
[17,]   NA        NA -117.2289 -117.2295
[18,]   NA        NA -117.2289 -117.2295
[19,]   NA        NA -117.2289 -117.2295
[20,]   NA        NA -117.2289 -117.2295
[21,]   NA        NA -117.2289 -117.2295
[22,]   NA        NA -117.2289 -117.2295
[23,]   NA        NA -117.2289 -117.2295
[24,]   NA        NA -117.2289 -117.2295
[25,]   NA        NA -117.2289 -117.2295
[26,]   NA        NA -117.2289        NA
[27,]   NA        NA -117.2289        NA
[28,]   NA        NA -117.2289        NA
[29,]   NA        NA -117.2289        NA
[30,]   NA        NA -117.2289        NA
[31,]   NA        NA -117.2289        NA
[32,]   NA        NA -117.2289        NA
[33,]   NA        NA -117.2289        NA
[34,]   NA        NA -117.2289        NA
[35,]   NA        NA -117.2289        NA
[36,]   NA        NA -117.2289        NA
[37,]   NA        NA -117.2289        NA
[38,]   NA        NA -117.2289        NA
[39,]   NA        NA -117.2289        NA
[40,]   NA        NA -117.2289        NA
[41,]   NA        NA -117.2289        NA
[42,]   NA        NA -117.2289        NA
[43,]   NA        NA        NA        NA
[44,]   NA        NA        NA        NA
[45,]   NA        NA        NA        NA

Firstly, I would like the output to be a single column for each variable instead of a data frame or matrix (and then perform my cbind outside of the loop). Also, I just want only the numeric outputs, the items that have actually been changed by going through the loops, with none of the NAs included (although I realize that right now most of the NAs are from my matrix dimensions). So, for example, my LON variable would be a single column with all of the numeric rows produced by the loops. A small sample of my desired output would look like this:

All the columns after the cbind:

         LAT       LON      Impute  ID
[475,]   32.81331 -117.2295      1 1021
[476,]   32.81331 -117.2295      1 1022
[477,]   32.81331 -117.2295      1 1023
[478,]   32.81331 -117.2295      1 1148
[479,]   32.81331 -117.2295      1 1149
[480,]   32.81331 -117.2295      1 1150
[481,]   32.81331 -117.2295      1 1151
[482,]   32.81331 -117.2295      1 1152
[483,]   32.81331 -117.2295      1 1153
[484,]   32.81331 -117.2295      1 1154
[485,]   32.81331 -117.2295      1 1155
[486,]   32.81331 -117.2295      1 1156
[487,]   32.81331 -117.2295      1 1157
[488,]   32.81331 -117.2295      1 1158

Finally, here is a sample of the second dataframe on my list (list of four) that represents the input:

[[2]]
    FIXTYPE       LON        LAT ACTIVITYIN Impute  ID
537       6 -117.2295   32.81602          0     NA 537
538       6 -117.2295   32.81602          0     NA 538
539       6 -117.2295   32.81602          0     NA 539
540       6 -117.2295   32.81602          0     NA 540
541       6 -117.2295   32.81602          0     NA 541
542       6 -117.2295   32.81602          0     NA 542
543       6 -117.2295   32.81602          0     NA 543
544       6 -117.2295   32.81602          0     NA 544
545       6 -117.2295   32.81602          0     NA 545
546       6 -117.2295   32.81602          0     NA 546
547       6 -117.2295   32.81602          0     NA 547
548       7 -180.0000 -180.00000          0     NA 548
549       7 -180.0000 -180.00000          0     NA 549
550       7 -180.0000 -180.00000          0     NA 550
551       7 -180.0000 -180.00000          1     NA 551
552       7 -180.0000 -180.00000          1     NA 552

Also, sorry this is so long, I just wanted to be super clear about my inputs, outputs and desired outputs. Any help would be really and truly appreciated as I've been working hard on this script for a while.

Edit: Due to comments, more detail on the input (subM.List) is below, and I have changed the sample of the input above to the second item on the list, which will actually be changed within the loops.

str(subM.List)
List of 4
 $ : num [1:11, 1:6] 5 5 5 5 5 5 5 5 5 5 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:11] "452" "453" "454" "455" ...
  .. ..$ : chr [1:6] "FIXTYPE" "LON" "LAT" "ACTIVITYIN" ...
 $ : num [1:137, 1:6] 6 6 6 6 6 6 6 6 6 6 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:137] "537" "538" "539" "540" ...
  .. ..$ : chr [1:6] "FIXTYPE" "LON" "LAT" "ACTIVITYIN" ...
 $ : num [1:315, 1:6] 5 5 5 5 5 5 5 5 5 5 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:315] "718" "719" "720" "721" ...
  .. ..$ : chr [1:6] "FIXTYPE" "LON" "LAT" "ACTIVITYIN" ...
 $ : num [1:26, 1:6] 5 5 5 5 5 5 5 5 5 5 ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : chr [1:26] "1134" "1135" "1136" "1137" ...
  .. ..$ : chr [1:6] "FIXTYPE" "LON" "LAT" "ACTIVITYIN" ...

Ok, I feel a little silly (ok, I feel really silly) that I didn't realize this before. Since my loop went ahead and actually replaced the values in my list everything that I needed as an output ended up being stored in subM.List post-loop. And to get my values into one data frame I simply 'unlisted':

loopOutput <- ldply(subM.List, data.frame)

Thanks for your patience everyone!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM