For loop inside lapply

I have the following simplified dataframe df (dput below):

> df
  group value
1     A     1
2     A     4
3     B     2
4     B     3
5     C     2
6     C     1

I would like to apply a for-loop per group using lapply. So first I created a list for each group using split. Then I would like to perform the for loop within each dataframe, but it doesn’t work. Here is some reproducible code (Please note a simplified for loop to make it reproducible):

df = data.frame(group = c("A", "A", "B", "B", "C", "C"),
                value = c(1, 4, 2, 3, 2, 1))

l = split(df, df$group)
lapply(l, \(x) {
  for(i in 1:nrow(x)) {
    if(x$value[i] == 1) {
      x$value[i] = x$value[i] + 1
    } else
      x$value[i] = x$value[i] + 2
  }
})
#> $A
#> NULL
#> 
#> $B
#> NULL
#> 
#> $C
#> NULL

Created on 2023-02-15 with reprex v2.0.2

This should add 1 to the values that are 1 otherwise add 2 (this is really simple but reproducible). As you can see it returns NULL. The expected output should look like this:

$A
  group value
1     A     2
2     A     6

$B
  group value
3     B     3
4     B     5

$C
  group value
5     C     4
6     C     2

So I was wondering how we can apply a for-loop to each group within a lapply? Why is it returning NULL?


dput df:

df<-structure(list(group = c("A", "A", "B", "B", "C", "C"), value = c(1, 
4, 2, 3, 2, 1)), class = "data.frame", row.names = c(NA, -6L))

>Solution :

A for loop aways returns a NULL value. If you want your function to return the updated x value, then make sure to add x to the end of the function, or return(x) to be more explicit.

l = split(df, df$group)
lapply(l, \(x) {
  for(i in 1:nrow(x)) {
    if(x$value[i] == 1) {
      x$value[i] = x$value[i] + 1
    } else
      x$value[i] = x$value[i] + 2
  }
  x
})

Leave a Reply