1

I want to create multiple columns using the apply function. The idea is to use the apply to create new columns using paste0 to define the name. Follows an example:


Name <- c("Jon", "Bill", "Maria", "Ben", "Tina")
Age <- c(23, 41, 32, 58, 26)
Number <- 1:4

df <- data.frame(Name, Age)

creating_columns <- function(number){
  df[paste0("new_",number)] <- number
  
 return(df) 
}

lapply(Number,creating_columns)

The code doesn't work. I have just a list of four different data frames, and in each one, I have a new column but I wanted the final data with all new columns. I can use for to create this, but my real data frame is too big so it takes too long. Follows the code that works:

for (number in Number){
  df[paste0("new_",number)] <- number
}

I want the following:

   Name Age new_1 new_2 new_3 new_4
1   Jon  23     1     2     3     4
2  Bill  41     1     2     3     4
3 Maria  32     1     2     3     4
4   Ben  58     1     2     3     4
5  Tina  26     1     2     3     4
  • 1
    I might be wrong, but I wouldn't expect notable increase in performance for this kind of task. – harre Aug 01 '22 at 17:30
  • I actually do some other operations before creating the columns, so it is not as simple as just putting the same number in the column. And I need to use the paste0 to get the right name of the column that I want to work with. – Maria Mittelbach Aug 01 '22 at 18:18

2 Answers2

3

apply/lapply would not be a great way to approach this. Variables modified in a function do not change outside that function thanks to scoping rules. It would be better to generate your new columns however you like, then bind them to the original data. For example

cbind(df, setNames(as.list(Number), paste0("new_", Number)))
#    Name Age new_1 new_2 new_3 new_4
# 1   Jon  23     1     2     3     4
# 2  Bill  41     1     2     3     4
# 3 Maria  32     1     2     3     4
# 4   Ben  58     1     2     3     4
# 5  Tina  26     1     2     3     4

Here we recreate a list from your numbers which act as the column values and then use setNames to give the columns new names

MrFlick
  • 195,160
  • 17
  • 277
  • 295
2

You can use <<- inside your function and will get your result as for loop , but it is not recommended to change the parent environment from a function

Name <- c("Jon", "Bill", "Maria", "Ben", "Tina")
Age <- c(23, 41, 32, 58, 26)
Number <- 1:4

df <- data.frame(Name, Age)

creating_columns <- function(number){
    df[paste0("new_",number)] <<- number
}

lapply(Number,creating_columns)
  • output
df

   Name Age new_1 new_2 new_3 new_4
1   Jon  23     1     2     3     4
2  Bill  41     1     2     3     4
3 Maria  32     1     2     3     4
4   Ben  58     1     2     3     4
5  Tina  26     1     2     3     4
Mohamed Desouky
  • 4,340
  • 2
  • 4
  • 19