2015-10-06 15 views
9

我可以使用下面的返回最大2列dplyr变异的列的范围内横行最大

newiris<-iris %>% 
rowwise() %>% 
mutate(mak=max(Sepal.Width,Petal.Length)) 

的我想要做的就是找到在一系列列是最大的,所以我没有命名每个像这样的

newiris<-iris %>% 
rowwise() %>% 
mutate(mak=max(Sepal.Width:Petal.Length)) 

任何想法?

回答

16

相反的rowwise(),这可以用pmax

iris %>% 
     mutate(mak=pmax(Sepal.Width,Petal.Length, Petal.Width)) 

做可能是我们可以使用interplibrary(lazyeval)如果我们想引用存储在一个vector的列名。

library(lazyeval) 
nm1 <- names(iris)[2:4] 
iris %>% 
    mutate_(mak= interp(~pmax(v1), v1= as.name(nm1))) 
+1

pmax的好主意。任何想法如何通过引用书挡找到3列的最大值?例如:Sepal.Width通过Petal.Width? – user2502836

+0

@ user2502836更新了帖子。请检查是否有帮助。 – akrun

2

对于选择某些列,而无需使用dplyr打字时,整个名字,我更喜欢从subset功能select参数。这样

可以得到想要的结果:

iris %>% subset(select = 2:4) %>% mutate(mak = do.call(pmax, (.))) %>% 
    select(mak) %>% cbind(iris) 
+1

我觉得我们可以只选'(2:4)'而不是'子集(select = 2:4)'。 –

0

好像@ akrun的答案只解决时,你可以在所有的变量的名称输入的情况下,不管是直接使用mutatemutate(pmax_value=pmax(var1, var2))或当使用mutate_interp通过mutate_(interp(~pmax(v1, v2), v1=as.name(var1), v2=as.name(var2))进行延迟评估。

如果您想使用冒号语法Sepal.Length:Petal.Width或者您碰巧有一个带有列名称的向量,我可以看到两种方法来执行此操作。

第一个更优雅。您可以整理数据并在分组时对数值取最大值:

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 

更难的方法是使用插值公式。如果你有一个字符向量,其变量的名字会被最大化,或者如果你的表格太高/宽了以至于不能整理,这很好。

# 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