dplyr mutate rowwise max of column范围

时间:2015-10-06 19:49:46

标签: r dplyr

我可以使用以下命令返回最多2列

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

我想要做的是在一系列列中找到最大值,这样我就不必像这样命名每一个

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

有什么想法吗?

7 个答案:

答案 0 :(得分:27)

而不是rowwise(),可以使用pmax

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

如果我们想引用存储在interp中的列名,我们可以使用library(lazyeval)中的vector

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

答案 1 :(得分:13)

使用rlang和半引号,我们还有另一个dplyr选项。首先,获取我们要为其计算并行最大值的行名称:

iris_cols <- iris %>% select(Sepal.Length:Petal.Width) %>% names()

然后,我们可以使用!!!rlang::syms为这些列的每一行计算并行最大值:

iris %>%
  mutate(mak=pmax(!!!rlang::syms(iris_cols)))
  • rlang::syms接受字符串输入(列名),并将其转换为符号
  • !!!取消引号并拼接其参数,此处为列名

哪个给:

    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

h / t:https://stackoverflow.com/a/47773379/1036500

答案 2 :(得分:3)

在使用dplyr时选择某些列而不输入全名,我更喜欢select函数中的subset参数。

你可以得到这样的结果:

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

答案 3 :(得分:3)

当前(dplyr 1.0.2)有效,

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

这也使您可以使用选择助手(starts_with等)。

答案 4 :(得分:0)

@ akrun的答案似乎只解决了您可以输入所有变量名称的情况,无论是直接使用mutate使用mutate(pmax_value=pmax(var1, var2))还是使用{{1}使用延迟评估}和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

答案 5 :(得分:0)

一种方法是将数据通过管道传递给select,然后使用使pmax按行排列的函数调用pmax(这与@inscaven的使用do.call的答案非常相似,不幸的是,没有不是R中的rowMaxs函数,所以我们必须使用一个函数使pmax逐行-在下面我使用purrr::pmap

library(dplyr)
library(purrr)

# to get the value of the max
iris$rowwisemax <- iris %>% select(Sepal.Width:Petal.Length) %>% pmap(pmax) %>% as.numeric

# to get the argmax
iris$whichrowwisemax <- iris %>% select(Sepal.Width:Petal.Length) %>% {names(.)[max.col(.)]}

答案 6 :(得分:0)

这是base-R解决方案:可以使用subset()选择一系列列名。可以使用transform()apply()的组合来添加按行最大值。

newiris <- transform(iris, mak = apply(subset(iris, select=Sepal.Width:Petal.Length), 1, max))