2 votes

Comment appliquer une fonction ligne par ligne dans un cadre de données en utilisant dplyr sans coder en dur les noms des colonnes ?

J'ai le cadre de données suivant :

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

Voici le code actuel que j'utilise pour calculer le score en codant en dur le nom de la colonne :

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))))

Ce qui produit :

# 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

Ce que je veux faire est de calculer chaque score, mais sans coder en dur le nom de la colonne.

Comment y parvenir ?

4voto

akrun Points 148302

Une concision base R L'option serait

dat$score <- do.call(pmax, dat)/rowSums(dat)

Sur tidyverse nous pouvons faire

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

1voto

Romain Francois Points 8223

Avec l'opérateur d'épissage sans guillemets !!! que vous pouvez faire :

> 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

Cela fonctionne en générant l'appel pour vous.

> 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)
)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X