I have this dataset:
toy <- cbind(ID = c(1:10),
group1 = sample(1:3, 10, replace = TRUE),
group2 = sample(1:3, 10, replace = TRUE),
value = rnorm(1:10))
ID group1 group2 value
[1,] 1 1 2 -0.32903883
[2,] 2 3 3 0.06923648
[3,] 3 1 1 0.09690423
[4,] 4 1 3 0.29003439
[5,] 5 3 2 -0.74667894
[6,] 6 1 2 -0.84689639
[7,] 7 3 3 1.19707766
[8,] 8 1 3 -0.54862736
[9,] 9 2 2 0.30304570
[10,] 10 1 3 -0.05697053
I want to write a function with two arguments: dataframe
, focal.var
.
the function takes a dataframe
, groups it by a group1
and takes the mean of focal.var
. I do not know how to pass the column names to mean()
function below. I tried this:
focal <- function(dataset, focal.var){
df <- dataset %>%
group_by(group1) %>%
mutate(FV_ft = mean(focal.var))
return(df)
after calling my function:
focal(dataset = toy, focal.var = "value")
produces this error:
argument is not numeric or logical: returning NA
CodePudding user response:
@rawr is correct. The linked answer shows passing a string containing a column name into group_by
. The process is no different when passing the string into summarise
:
This is the approach I typically use:
library(dplyr)
focal <- function(dataset, focal.var){
df <- dataset %>%
group_by(group1) %>%
mutate(FV_ft = mean(!!sym(focal.var)))
return(df)
}
This is an approach recommended by the programming with dplyr vignette:
library(dplyr)
focal <- function(dataset, focal.var){
df <- dataset %>%
group_by(group1) %>%
mutate(FV_ft = mean(.data[[focal.var]]))
return(df)
}
CodePudding user response:
We could use curly-curly
{{}}
: And I have added one more argument for the group:
library(dplyr)
library(tibble)
focal <- function(dataset, group, focal.var){
df <- dataset %>%
as_tibble() %>%
group_by({{group}}) %>%
mutate(FV_ft = mean({{focal.var}}, na.rm=TRUE))
return(df)
}
focal(toy, group1, value)
ID group1 group2 value FV_ft
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 2 1 -0.653 0.160
2 2 2 3 0.820 0.160
3 3 2 2 1.48 0.160
4 4 3 3 -0.929 -0.929
5 5 2 1 -0.182 0.160
6 6 2 1 1.00 0.160
7 7 2 1 -0.852 0.160
8 8 1 3 -1.72 -0.326
9 9 2 2 -0.495 0.160
10 10 1 3 1.07 -0.326
CodePudding user response:
Seems like the answer is a one liner:
FV_ft = mean(eval(as.name(focal.var)))