如何使用modify_if将每个数字列除以另一列?

时间:2019-08-04 22:34:02

标签: r purrr

我想将数据框中满足条件的每一列除以同一数据框内的一列

我相信可以用多种方法来完成,但是我觉得如果我可以使用专为这种类型的工作设计的purrr软件包来做,那对我来说会更有效率。

例如,这有效

t <- iris %>% 
  modify_if(is.numeric, ~./2)

但这不是

t <- iris %>% 
  modify_if(is.numeric, ~./Sepal.Length)

这会导致错误

Error in .f(.x[[i]], ...) : object 'Sepal.Length' not found

我认为它希望我将.y指定为“ Sepal.Length”,但我找不到正确的方法。

我对Modify2,imodify,map2和pmap感到困惑

如果您能为我提供有关正确使用purrr的适当指南,我将不胜感激。对于概念和直觉,官方指南似乎还不错
 但我正在努力将其应用。 https://purrr.tidyverse.org/reference/modify.html

1 个答案:

答案 0 :(得分:1)

在这种情况下,要使用modify_if,我们可以做

library(dplyr)
library(purrr)

iris %>% modify_if(is.numeric, ~./iris$Sepal.Length)

#    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
#1              1   0.6862745    0.2745098  0.03921569     setosa
#2              1   0.6122449    0.2857143  0.04081633     setosa
#3              1   0.6808511    0.2765957  0.04255319     setosa
#4              1   0.6739130    0.3260870  0.04347826     setosa
#5              1   0.7200000    0.2800000  0.04000000     setosa
#6              1   0.7222222    0.3148148  0.07407407     setosa
#....

或其他版本

iris %>%  modify_if(is.numeric, function(x) x/.$Sepal.Length)

或如@Artem Sokolov所建议

iris %>% modify_if(is.numeric, `/`, .$Sepal.Length)

另一种方法是使用mutate_if,但是为此,您需要按照@neilfws的说明重新排列列

iris %>%
  select(Sepal.Width, Petal.Length, Petal.Width, Species, Sepal.Length) %>%
  mutate_if(is.numeric, ~./Sepal.Length)

最后使用基数R

iris[] <- lapply(iris, function(x) if(is.numeric(x)) x/iris$Sepal.Length else x)
#OR
cols <- sapply(iris, is.numeric)
iris[cols] <- lapply(iris[cols], function(x) x/iris$Sepal.Length)