rfor-looptidyrrbindcbind

In loop over dataframe rows, how to append list to dataframe


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

Solution

  • 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
    # ...