【问题标题】:How to use modify_if to divide each numeric column by another column?如何使用 modify_if 将每个数字列除以另一列?
【发布时间】:2019-08-04 22:34:02
【问题描述】:

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

我相信它可以通过多种方式完成,但我觉得如果我可以使用专为此类工作设计的 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

【问题讨论】:

  • 对我来说 (dplyr-0.8.1),这可以正常工作:iris %&gt;% mutate_if(is.numeric, ~ ./Sepal.Length)
  • @r2evans 确实可以正常工作,但如果您检查结果,则只有 Sepal.Length 列是正确的。这是因为它是第一列,所以它自己除以 1,然后所有其他列除以 1不变。
  • 哎呀,对不起,我读了modify_if 并认为mutate_if,...
  • 如果列被重新排序以将 Sepal.Length 放在最后,您可以使用 mutate_if

标签: r purrr


【解决方案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)

最后使用base 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)

【讨论】:

  • 又一个版本:iris %&gt;% modify_if(is.numeric, `/`, .$Sepal.Length)
  • @ArtemSokolov 我认为这可能是我正在寻找的解决方案。您能否使用iris %&gt;% modify_if(.p = is.numeric, .f = `/`, .y = .$Sepal.Length) 之类的显式参数对其进行编辑
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多