-1

This is just a simplified example of what I am trying to accomplish:

I have nine objects (named A1-A9), each containing 3 random numbers. I want the mean of these three numbers for each object. That's easy enough for me to accomplish on my own:

lapply(1:9, function(y){
  mean(A[y]) 
})

The catch is, I want that mean value to become the fourth value in each object. So, the fourth value in A1 is the mean of the first three values in A1, and etc. Again I could do that, but all I can think of is to just run the mean() function nine times for each object. Is it possible to loop through those existing variable names within a lapply (or any) loop in R? So, something to this effect, but that actually works:

lapply(1:8, function(y){
  A[y][4] <- mean(A[y]) 
})

Where the unique part of the object name is looped (y), and the result of the function is assigned to it in the fourth spot.

MarkC
  • 1
  • 1
    Do you have nine objects `A1, A2 .. A9` (as per your text) or do you have one list A with nine numbered elements `A[1], A[2] .. A[9]` (as per your first example)? – Ottie Aug 12 '22 at 15:56
  • 2
    It's easier to help you if you provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. So you actually have variables with indexes in their names? That's usually a sign you should be using a list instead to old your values. That makes applying functions over the list much easier. – MrFlick Aug 12 '22 at 15:57
  • @Ottie I have nine objects. Using lapply to generate a list of nine mean values is just the only way that I can think of currently to do this with a loop. – MarkC Aug 12 '22 at 16:01
  • @MrFlick The actual objects that I am working with are already lists; I didn't want to include them because they are unpublished data. So I want to add a level to each list that is created by performing a function on an existing level of each list object. And I am just curious if it is possible to accomplish this with a loop, rather than just running the function multiple times separately – MarkC Aug 12 '22 at 16:03
  • 2
    Sorry, that still doesn't help. Please post a reproducible example using `dput` as @MrFlick says - you don't have to include any sensitive data (just replace the real names/numbers with gibberish, but leave the data structures) and, frankly, we really don't care to scoop your analysis. – Ottie Aug 12 '22 at 16:10

1 Answers1

1

You could do:

lapply(1:9, function(y) c(A[[y]], mean(A[[y]])))

However, it would be easier for you to parse the full list to lapply:

lapply(A, function(y) c(y, mean(y)))

Why it works:

  • Use c to add an element to each vector in the list
  • Use [[ to get into each element of the list.

Example:

A <- list(A1 = c(1,2,3), A2 = c(2,3,4), A3 = c(3,4,5))
lapply(A, function(y) c(y, mean(y)))

Output:

[[1]]
[1] 1 2 3 2

[[2]]
[1] 2 3 4 3

[[3]]
[1] 3 4 5 4

Update:

If you have A1..A9 objects as indicated in the comments - not within a list - you would probably want to put them into one from the very beginning. Now that this isn't the case, a hacky way could be to grab all objects in the format A followed by digit using regex and put them into a list:

list_of_As <- mget(ls(pattern = "A\\d"))
lapply(list_of_As, function(y) c(y, mean(y)))

Output:

$A1
[1] 1 2 3 2

$A2
[1] 2 3 4 3

$A3
[1] 2 3 4 3
harre
  • 7,081
  • 2
  • 16
  • 28