I have two vectors of names in my database (say one represent a component and second represent values) and I'm trying to develop a function that would create new columns based of the two vectors in a generalizable way I.E. something along the line of :
#vector components and values contain column names from the dataset
creaYK<-function(data,Input="A",Components=c("A", "B", "C"),Values=c("D", "E", "F")){
for(i in 1:length(Values)){
data<-data%>%mutate(new_i = sum(Values[i],Components[i]))
}
}
my problem is that I need my arguments "vec1" and "vec2" to be modifiable in content and length and the calculation to be performed pairwise (each element of vec1 being summed to the corresponding in vec2). I have tried something with across()
but it failed.
here is the desired output :
vec1<-c("A","B","C")
vec2<-c("D","E","F")
data<-tibble(A=1,B=2,C=3,D=4,E=5,F=6)
# what I want is a function returning :
# function(data,vec1,vec2)
tibble(A=1,B=2,C=3,D=4,E=5,F=6,ad=5,be=7,cf=9)
But the code above only creates one new column,and my attempts with mutate were also unsuccessful
Moreover, the name of indicators are not structured in the same way as the name of the value used
CodePudding user response:
If I understand you correctly, you might want
library(dplyr)
a <- c(2,5,6)
b <- c(4,9,6)
df <- as.data.frame(cbind(a,b))
tribble <- function(data,vec1,vec2){
sum_v1v2 <- vec1 vec2
a <- data %>% mutate(Sum_of_components = sum_v1v2)
}
b <- tribble(df,a,b)
Output:
a b Sum_of_components
1 2 4 6
2 5 9 14
3 6 6 12
CodePudding user response:
Your question is a little unclear, but here's an attempt. We can use Map
to sum the values at the provided indices pairwise, and then use Map
again to generate column names. Finally, cbind
it all together:
library(tidyverse)
vec1<-c("A","B","C")
vec2<-c("D","E","F")
data<-tibble(A=1,B=2,C=3,D=4,E=5,F=6)
my_func <- function(data, vec1, vec2) {
sums <- Map(\(lhs, rhs) {
data[[lhs]] data[[rhs]]
}, vec1, vec2) %>%
as.data.frame()
names <- Map(paste0, vec1, vec2) %>%
unlist() %>%
tolower()
names(sums) <- names
return(cbind(data, sums))
}
result <- my_func(data, vec1, vec2)
A B C D E F ad be cf
1 2 3 4 5 6 5 7 9
You could also do this in a loop, taking advantage of dplyr's dynamic column naming capabilities. But this is a very unorthodox approach:
for (i in seq_along(vec1)) {
col1 <- vec1[i]
col2 <- vec2[i]
colname <- tolower(paste0(col1, col2))
data <- data %>%
mutate({{colname}} := cur_data()[[col1]] cur_data()[[col2]])
}