Reputation: 5169
I have the following data frame:
dat <- structure(list(setosa = c(50L, 0L, 0L), versicolor = c(0L, 11L,
39L), virginica = c(0L, 36L, 14L)), .Names = c("setosa", "versicolor",
"virginica"), row.names = c("1", "2", "3"), class = "data.frame")
dat
#> setosa versicolor virginica
#> 1 50 0 0
#> 2 0 11 36
#> 3 0 39 14
This is the current code I use to calculate the score by hard-coding the column name into it:
library(dplyrj)
dat %>%
rowwise() %>%
# here I hard code the column names into the score
mutate(score = max(c(setosa,versicolor, virginica)/ sum(c(setosa, versicolor, virginica))))
Which produces:
# A tibble: 3 x 4
setosa versicolor virginica score
<int> <int> <int> <dbl>
1 50 0 0 1.00
2 0 11 36 0.766
3 0 39 14 0.736
What I want to do is to calculate each score, but without hard coded the column name.
How can achieve that?
Upvotes: 2
Views: 89
Reputation: 17642
With the unquote splice operator !!!
, you can do:
> library(tidyverse)
> psum <- function(...) reduce(list(...), `+` )
> mutate( dat, core = pmax(!!!syms(names(dat))) / psum(!!!syms(names(dat))) )
setosa versicolor virginica core
1 50 0 0 1.0000000
2 0 11 36 0.7659574
3 0 39 14 0.7358491
That works by generating the call for you, i.e.
> rlang::qq_show( mutate( dat, core = pmax(!!!syms(names(dat))) / psum(!!!syms(names(dat))) ) )
mutate(dat, core = pmax(setosa, versicolor, virginica) /
psum(setosa, versicolor, virginica)
)
Upvotes: 1
Reputation: 887941
A concise base R
option would be
dat$score <- do.call(pmax, dat)/rowSums(dat)
In tidyverse
we can do
library(tidyverse)
dat %>%
mutate(score = do.call(pmax, .)/reduce(., `+`))
# setosa versicolor virginica score
#1 50 0 0 1.0000000
#2 0 11 36 0.7659574
#3 0 39 14 0.7358491
Upvotes: 3