dplyr对列的行最大范围进行变异

dplyr对列的行最大范围进行变异,r,dplyr,R,Dplyr,我可以使用以下命令返回最多2列 newiris<-iris %>% rowwise() %>% mutate(mak=max(Sepal.Width,Petal.Length)) newiris% 行() 变异(mak=max(萼片宽度,花瓣长度)) 我想做的是在一系列列中找到最大值,这样我就不必这样命名每一列了 newiris<-iris %>% rowwise() %>% mutate(mak=max(Sepal.Width:Petal.Len

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

newiris<-iris %>%
 rowwise() %>%
 mutate(mak=max(Sepal.Width,Petal.Length))
newiris%
行()
变异(mak=max(萼片宽度,花瓣长度))
我想做的是在一系列列中找到最大值,这样我就不必这样命名每一列了

newiris<-iris %>%
 rowwise() %>%
 mutate(mak=max(Sepal.Width:Petal.Length))
newiris%
行()
变异(mak=max(萼片宽度:花瓣长度))
有什么想法吗?

可以使用
pmax来代替
rowwise()

iris %>%
      mutate(mak=pmax(Sepal.Width,Petal.Length, Petal.Width))
如果我们想引用存储在
向量中的列名,可以使用
library(lazyeval)
中的
interp

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

对于在使用
dplyr
时选择一些列而不键入全名,我更喜欢
子集
函数中选择
参数

您可以得到如下所示的预期结果:

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

似乎@akrun的答案只解决了您可以输入所有变量名称的情况,无论是使用
mutate
直接使用
mutate(pmax\u value=pmax(var1,var2))
还是通过
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

使用
rlang
和准旋转,我们有另一个dplyr选项。首先,获取我们要计算并行最大值的行名称:

iris_cols <- iris %>% select(Sepal.Length:Petal.Width) %>% names()
  • 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:

一种方法是将数据导入select,然后使用一个使
pmax
成行的函数调用
pmax
(这与@inscaven使用
do.call
的答案非常相似,不幸的是,R中没有
rowMaxs
函数,因此我们必须使用一个函数按行生成
pmax
——下面我使用了
purr::pmap

库(dplyr)
图书馆(purrr)
#以获取最大值的值
虹膜$rowwisemax%选择(萼片宽度:花瓣长度)%%>%pmap(pmax)%%>%as.numeric
#获取argmax
虹膜$whichrowwisemax%select(萼片.宽度:花瓣.长度)%>%{names(.)[max.col(.)]}
目前(dplyr 1.0.2),它的工作原理是:

newiris<-iris %>%
 rowwise() %>%
 mutate(mak=max(c_across(Sepal.Width:Petal.Length)))
newiris%
行()
变异(mak=max(c_交叉(萼片宽度:花瓣长度)))

这还允许您使用选择帮助程序(从etc开始)。

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


newiris关于pmax的好主意。你知道我如何通过引用书尾来找到3列中的最大值吗?例如:Sepal.Width through Petal.Width?@user2502836更新了帖子。请检查这是否有帮助。我想你可以只做
select(2:4)
而不是
subset(select=2:4)
。使用
dplyr 1.0.1
您的第二个示例可以完美地工作。如果您想要包含最大值的列的索引,也可以将
max()
替换为
which.max()
    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
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(.)]}

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