Je peux utiliser ce qui suit pour renvoyer le maximum de 2 colonnes
newiris<-iris %>%
rowwise() %>%
mutate(mak=max(Sepal.Width,Petal.Length))
Ce que je veux faire est de trouver ce maximum sur une plage de colonnes afin de ne pas avoir à les nommer comme ceci
newiris<-iris %>%
rowwise() %>%
mutate(mak=max(Sepal.Width:Petal.Length))
Des idées?
Au lieu de rowwise()
, ceci peut être fait avec pmax
iris %>%
mutate(mak=pmax(Sepal.Width,Petal.Length, Petal.Width))
Peut-être pouvons-nous utiliser interp
à partir de library(lazyeval)
si nous voulons référencer les noms de colonne stockés dans une vector
.
library(lazyeval)
nm1 <- names(iris)[2:4]
iris %>%
mutate_(mak= interp(~pmax(v1), v1= as.name(nm1)))
Avec rlang
et la quasiquotation, nous avons une autre option dplyr. Commencez par obtenir les noms de lignes pour lesquels nous voulons calculer le nombre maximal de parallèles:
iris_cols <- iris %>% select(Sepal.Length:Petal.Width) %>% names()
Ensuite, nous pouvons utiliser !!!
et rlang::syms
pour calculer le maximum parallèle pour chaque ligne de ces colonnes:
iris %>%
mutate(mak=pmax(!!!rlang::syms(iris_cols)))
rlang::syms
prend une entrée de chaîne (les noms de colonne) et la transforme en symbole!!!
entre guillemets et raccorde son argument, ici les noms de colonnesQui donne:
Sepal.Length Sepal.Width Petal.Length Petal.Width Species mak
1 5.1 3.5 1.4 0.2 setosa 5.1
2 4.9 3.0 1.4 0.2 setosa 4.9
3 4.7 3.2 1.3 0.2 setosa 4.7
4 4.6 3.1 1.5 0.2 setosa 4.6
5 5.0 3.6 1.4 0.2 setosa 5.0
Pour sélectionner certaines colonnes sans taper des noms entiers lors de l'utilisation de dplyr
, je préfère le paramètre select
de la fonction subset
.
Vous pouvez obtenir le résultat souhaité comme ceci:
iris %>% subset(select = 2:4) %>% mutate(mak = do.call(pmax, (.))) %>%
select(mak) %>% cbind(iris)
Il semble que la réponse de @ akrun ne concerne que les cas dans lesquels vous pouvez taper le nom de toutes les variables, que ce soit en utilisant mutate
directement avec mutate(pmax_value=pmax(var1, var2))
ou en utilisant une évaluation différée avec mutate_
et interp
via mutate_(interp(~pmax(v1, v2), v1=as.name(var1), v2=as.name(var2))
.
Je peux voir deux façons de procéder si vous souhaitez utiliser la syntaxe du côlon Sepal.Length:Petal.Width
ou si vous avez un vecteur avec les noms de colonne.
Le premier est plus élégant. Vous rangez les données et prenez le maximum parmi les valeurs regroupées:
data(iris)
library(dplyr)
library(tidyr)
iris_id = iris %>% mutate(id=1:nrow(.))
iris_id %>%
gather('attribute', 'value', Sepal.Length:Petal.Width) %>%
group_by(id) %>%
summarize(max_attribute=max(value)) %>%
right_join(iris_id, by='id') %>%
head(3)
## # A tibble: 3 × 7
## id max_attribute Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## <int> <dbl> <dbl> <dbl> <dbl> <dbl> <fctr>
## 1 1 5.1 5.1 3.5 1.4 0.2 setosa
## 2 2 4.9 4.9 3.0 1.4 0.2 setosa
## 3 3 4.7 4.7 3.2 1.3 0.2 setosa
La méthode la plus difficile consiste à utiliser une formule interpolée. C'est bien si vous avez un vecteur de caractère avec les noms des variables sur lesquelles vous souhaitez appliquer une valeur maximale ou si la table est trop grande/trop large pour pouvoir être rangée.
# Make a character vector of the names of the columns we want to take the
# maximum over
target_columns = iris %>% select(-Species) %>% names
## [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"
# Make a vector of dummy variables that will take the place of the real
# column names inside the interpolated formula
dummy_vars = sapply(1:length(target_columns), function(i) sprintf('x%i', i))
## [1] "x1" "x2" "x3" "x4"
# Paste those variables together to make the argument of the pmax in the
# interpolated formula
dummy_vars_string = paste0(dummy_vars, collapse=',')
## [1] "x1,x2,x3,x4"
# Make a named list that maps the dummy variable names (e.g., x1) to the
# real variable names (e.g., Sepal.Length)
dummy_vars_list = lapply(target_columns, as.name) %>% setNames(dummy_vars)
## $x1
## Sepal.Length
##
## $x2
## Sepal.Width
##
## $x3
## Petal.Length
##
## $x4
## Petal.Width
# Make a pmax formula using the dummy variables
max_formula = as.formula(paste0(c('~pmax(', dummy_vars_string, ')'), collapse=''))
## ~pmax(x1, x2, x3, x4)
# Interpolate the formula using the named variables
library(lazyeval)
iris %>%
mutate_(max_attribute=interp(max_formula, .values=dummy_vars_list)) %>%
head(3)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species max_attribute
## 1 5.1 3.5 1.4 0.2 setosa 5.1
## 2 4.9 3.0 1.4 0.2 setosa 4.9
## 3 4.7 3.2 1.3 0.2 setosa 4.7