Reputation: 53
I am currently trying to write a simple custom function which creates a new column in an existing data.frame, based on a multiplication of two existing columns.
Following that I would like to apply the function across multiple data.frames in the global environment with lapply.
I however already fail to write the custom function, as I am getting the follow error (based on my example data posted below): "In [<-.data.frame
(*tmp*
, i, value = list(A = 1:20, B = c(1L, : provided 3 variables to replace 2 variables"
I am aware that this is an absolute basic question, but I have not found a fitting answer to this specific question online and simply cant wrap my head around it myself.
Thanks in advance for any help!
I have already tried using "return(x[i])" at the end of the function, as it has been recommended in other posts, or also leaving out the [i] (which I am only using as I saw it another question), which did not change anything.
Using this function gives the error stated above
set.seed(40)
A <- seq(1:20)
B <- rbinom(A, 1, 0.5)
df1 <- data.frame(A, B)
set.seed(40)
C <- as.numeric(seq(1:50))
D <- as.numeric(rbinom(C, 1, 0.5))
df2 <- data.frame(C, D)
FUN = function(x, i){
x[i]$Mul = x[i]$A*x[i]$B
}
FUN(df1)
This function correctly gives the new values but of course does not create a new column in the existing data.frame
FUN = function(x, i){
x[i]$A*x[i]$B
}
FUN(df1)
I would then like to apply the function with to all other data.frames including "df" in the name
lapply(mget(ls(pattern="df")), FUN)
I excpet to have a new column in df, df$Mul, with the values c( 1 2 3 0 0 0 0 8 0 0 0 12 0 0 15 16 0 18 0 20). Such a column, I cant manage to create.
Upvotes: 2
Views: 126
Reputation: 887118
We can use tidyverse
methods
library(tidyverse)
mget(ls(pattern = "^df\\d+$")) %>%
map(~ .x %>%
mutate(mult = (!! rlang::sym(names(.x)[1])) *
(!! rlang::sym(names(.x)[2]))))
Or using reduce
mget(ls(pattern = "^df\\d+$")) %>%
map(~ .x %>%
mutate(mult = reduce(., `*`)))
Upvotes: 1
Reputation: 388982
You could get all the dataframes together in a list using mget
list_df <- mget(ls(pattern="df"))
Change the function using transform
FUN = function(x){
transform(x, mult = x[, 1] * x[, 2])
}
and apply it to list of dataframes
list_df <- lapply(list_df, FUN)
You'll have all the dataframes with new column. Although, it is better to keep such dataframes in list instead of having objects of multiple dataframes in the global environment. However, if you want the dataframes separately again you can do
list2env(list_df,envir=.GlobalEnv)
Upvotes: 0