0

I want to loop through elements of different data.frames with the same number or ID: df1, df3, df4, df66, df76, in addition we have pp1, pp3, pp4, pp66, pp76 and dd1, dd3, dd4, dd66, dd76. Every data.frame has two columns frequency and energy:

df1 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df3 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df4 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df66 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
df76 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))

pp1 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp3 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp4 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp66 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
pp76 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))

dd1 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd3 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd4 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd66 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))
dd76 = as.data.frame(cbind("frequency"= runif(140) ,"energy"=runif(140)))

So first we create an ID vector to loop through those numbers

ID = c(1, 3, 4, 66, 76)

I tried this and well obviously is not working

for (i in ID){
   dfmaster[i] <-  df[i]$frequency + pp[i]$frequency + dd[i]$frequency
}

I also tried to use paste0 as:

for (i in ID){
   paste0("dfmaster",i) <-  paste0("df",i)+paste0("pp",i)+paste0("dd",i)}

Because this will create a character. But is actually how I would do with for example matlab.

Ra Koon
  • 19
  • 5
  • Could you please make the question reproducible and include an example of the expected output [Link for guidance on asking questions](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – Peter Nov 25 '21 at 09:19
  • The objects added to the question are named vectors: `str(df1)` rather than data frames `is.data.frame(df1)` . Is there only one value for `frequency` and `energy` associated with each df# object? – Peter Nov 25 '21 at 13:52
  • No actually should be about 140 values, but for simplicity just one value was added... – Ra Koon Nov 25 '21 at 16:16

1 Answers1

1

@Peter's comment about making a reproducible example is very relevant but your question is clear enough to give some general advice although, in the absence of test data, this is all untested code.

The "R-way" of looping through objects is to use lists. You can put your standalone objects into lists like this:

dfList <- list(df1, df3, df4, df66, df76)
ppList <- list(pp1, pp3, pp4, pp66, pp76)
ddList <- list(dd1, dd3, dd4, dd66, dd76)

Though it would be more efficient to create them and the list at the same time.

Once the objects are in lists you can write:

dfMaster <- lapply(
              1:length(dfList),
              function(i) {
                dfList[[i]]$frequency + ppList[[i]]$frequency + ddList[[i]]$frequency
              }
            )

where lapply applies the function in the second argument to each element of its first argument and returns a list.

Alternatively, if you want to use a for loop you can write:

dfMaster <- list()

for(i in 1:length(dfList)) {
  dfMaster[[i]] <- dfList[[i]]$frequency + 
                     ppList[[i]]$frequency + ddList[[i]]$frequency
}

[Note that here you need to declare an empty list to contain the results of the for loop before running the loop.]

Though I generally avoid for loops because you can easily be caught out by lazy evaluation.

If the IDs are relevant, you can name the elements of your lists;

ID <- c(1, 3, 4, 66, 76)
names(dfList) <- ID
names(ppList) <- ID
names(ddList) <- ID

dfMaster <- lapply(
  ID,
  function(i) {
    dfList[[i]]$frequency + ppList[[i]]$frequency + ddList[[i]]$frequency
  }
)

Or name the elements of the list as you create it:

dfList <- list("1"=df1, "3"=df3, "4"=df4, "66"=df66, "76"=df76)
Limey
  • 10,234
  • 2
  • 12
  • 32
  • Thank you so much for your suggestion(s). When I use the test data, I get the following error on the for loop: Error: $ operator is invalid for atomic vectors – Ra Koon Nov 25 '21 at 10:19
  • As both @Peter and I have already commented, it is not possible to give detailed advice in the absence of test data. You maximise your chance of getting a useful answer if you provide a minimum reproducible example. [This post](https://stackoverflow.com/help/minimal-reproducible-example) may help. Please read the advice in the links we have given and update your question accordingly. – Limey Nov 25 '21 at 10:30
  • Thanks again! The question was edited with an example, but actually you answered the more generalised question and that was the aim of the question. THANKS :D – Ra Koon Nov 25 '21 at 12:01