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
})