In a for loop that loops over rows of a dataframe, I calculate results based on the values in the dataframe columns. How can I append the results (a list) into new columns in the dataframe? Example below is a dummy function, the real function is more complicated, and the approach needs to call the function instead of trying to re-create it. Looking for solutions that compare approaches in base R and tidyverse.
X <- seq(0,9,3)
Y <- seq(0,4,1)
vals <- c(100,200,300)
dummy_func <- function(x,y,z) {
return(x+y*z)
}
df <- merge(x=data.frame(X), y=data.frame(Y),all.x=TRUE, all.y=TRUE)
print(df)
X | Y |
---|---|
0 | 0 |
3 | 0 |
6 | 0 |
9 | 0 |
0 | 1 |
3 | 1 |
etc | etc |
for (row in 1:nrow(df)) {
result <- dummy_func(df$X[row], df$Y[row], vals)
# append this result to new columns
}
Desired dataframe:
X | Y | V1 | V2 | V3 |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
3 | 0 | 3 | 3 | 3 |
6 | 0 | 6 | 6 | 6 |
9 | 0 | 9 | 9 | 9 |
0 | 1 | 100 | 200 | 300 |
3 | 1 | 103 | 203 | 303 |
etc | etc | etc | etc | etc |
Base R attempt, as tidyverse isn't my strength.
Map
is the workhorse here, passing the X
and Y
vectors to the dummy_func()
function, while looping over each of the values in vals
as the final argument:
df[paste0("V",seq_along(vals))] <- Map(dummy_func, df["X"], df["Y"], vals)
df
# X Y V1 V2 V3
#1 0 0 0 0 0
#2 3 0 3 3 3
#3 6 0 6 6 6
#4 9 0 9 9 9
#5 0 1 100 200 300
#6 3 1 103 203 303
#7 6 1 106 206 306
# ...