Ich kann das Folgende verwenden, um das Maximum von 2 Spalten zurückzugeben
newiris<-iris %>%
rowwise() %>%
mutate(mak=max(Sepal.Width,Petal.Length))
Was ich tun möchte, ist, das Maximum über eine Reihe von Spalten zu finden, sodass ich nicht jeden so benennen muss
newiris<-iris %>%
rowwise() %>%
mutate(mak=max(Sepal.Width:Petal.Length))
Irgendwelche Ideen?
Anstelle von rowwise()
kann dies mit pmax
erfolgen.
iris %>%
mutate(mak=pmax(Sepal.Width,Petal.Length, Petal.Width))
Möglicherweise können wir interp
von library(lazyeval)
verwenden, wenn wir auf die in einer vector
gespeicherten Spaltennamen verweisen möchten.
library(lazyeval)
nm1 <- names(iris)[2:4]
iris %>%
mutate_(mak= interp(~pmax(v1), v1= as.name(nm1)))
Mit rlang
und quasiquotation haben wir eine weitere Option von dplyr. Rufen Sie zunächst die Zeilennamen ab, für die Sie das parallele Maximum berechnen möchten:
iris_cols <- iris %>% select(Sepal.Length:Petal.Width) %>% names()
Dann können wir !!!
und rlang::syms
verwenden, um das parallele Maximum für jede Zeile dieser Spalten zu berechnen:
iris %>%
mutate(mak=pmax(!!!rlang::syms(iris_cols)))
rlang::syms
nimmt eine Zeichenfolgeingabe (die Spaltennamen) in ein Symbol ein!!!
hebt das Anführungszeichen auf und fügt es zusammen, hier die SpaltennamenWas gibt:
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
Für die Auswahl einiger Spalten ohne die Eingabe von ganzen Namen bei der Verwendung von dplyr
bevorzuge ich den select
-Parameter aus der subset
-Funktion.
Sie können das gewünschte Ergebnis wie folgt erhalten:
iris %>% subset(select = 2:4) %>% mutate(mak = do.call(pmax, (.))) %>%
select(mak) %>% cbind(iris)
Es scheint, als würde die Antwort von @ akrun nur die Fälle ansprechen, in denen Sie die Namen aller Variablen eingeben können, ob mutate
direkt mit mutate(pmax_value=pmax(var1, var2))
oder Lazy Evaluation mit mutate_
und interp
über mutate_(interp(~pmax(v1, v2), v1=as.name(var1), v2=as.name(var2))
verwendet wird.
Ich habe zwei Möglichkeiten, dies zu tun, wenn Sie die Doppelpunkt-Syntax Sepal.Length:Petal.Width
verwenden möchten oder wenn Sie einen Vektor mit den Spaltennamen haben.
Der erste ist eleganter. Sie säubern die Daten und nehmen in der Gruppierung das Maximum unter den Werten auf:
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
Der schwierigere Weg ist die Verwendung einer interpolierten Formel. Dies ist sinnvoll, wenn Sie einen Zeichenvektor mit den Namen der Variablen haben, für die das Maximum festgelegt werden soll, oder wenn die Tabelle zu groß/zu breit ist, um sie zu säubern.
# 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