for-looperror-handlingapplycbindrep

duplicate and cbind multiple columns of data frame several but different times


assuming I have the following two data frames

set.seed(20)
df1 <- as.data.frame(matrix(runif(n=700, min=1, max=10), nrow=10))
df2 <- data.frame("name" = colnames(df1), "n" = round(runif(n=10, min=1, max=20), 0))
head(df1[1:3])
head(df2)

and I want to duplicate and cbind every column of df1 df2$n-1 times. Basically, I want to do this

df1 <- cbind(df1, rep(df1[1],4-1))
df1 <- cbind(df1, rep(df1[2],1-1))
df1 <- cbind(df1, rep(df1[3],11-1))
...

for every column of df1 and probably would have finished by now doing it for all of the 70 variables separately :D but I want to find the elegant solution.

How can I do that efficiently? I guess a for loop or something with the apply family would work but I couldnt get it right. Also, the error in for loop or apply when df2$n==1 like with df1[2] should just be skipped since this column should not be duplicated.

Thanks for your help!


Solution

  • Ok my thoughts were way too complicated and I tried stuff like this

    for (col in 1:ncol(df1)) {
      for (n in 1:nrow(df2)) {
        if (df2[n,2]==1) {
         next
        }
        if (col > 70) {
         break
        }
        df1 <- cbind(df1, rep(df1[col],df2[n,2]-1))
      }
    }
    

    which did not work properly. The answer (adapted from here How to duplicate columns in a data frame) is simply

    df1 <- df1[rep(names(df1), c(df2$n))]