首页 > 解决方案 > mutate_if - 警告信息

问题描述

大家好,

library(dplyr)
library(tibble)
mtcars %>%
  rownames_to_column("modelle") %>%
  mutate_if(~is.numeric(.x) & mean(.x) > 50, ~(.x / 1000))

Warning message:
In mean.default(.x) : argument is not numeric or logical: returning NA

这个错误似乎是因为字符向量。它有效,但它仍然非常丑陋。我有没有做错什么,在这种情况下可以做得更好吗?

谢谢!

标签: rdplyr

解决方案


R 不会短路 vectorized ,&因此它在所有列上都运行。 由于您的第一列 ( ) 显然是,因此它失败了。is.numericmeanmodellecharacter

但是,您实际上不需要对其进行矢量化。如果您从 vectorized 更改&为 binary &&,R 会将其短路并获得您想要的行为。

mtcars %>%
  rownames_to_column("modelle") %>%
  mutate_if(~is.numeric(.x) && mean(.x) > 50, ~(.x / 1000)) %>%
  head()
#             modelle  mpg cyl  disp    hp drat    wt  qsec vs am gear carb
# 1         Mazda RX4 21.0   6 0.160 0.110 3.90 2.620 16.46  0  1    4    4
# 2     Mazda RX4 Wag 21.0   6 0.160 0.110 3.90 2.875 17.02  0  1    4    4
# 3        Datsun 710 22.8   4 0.108 0.093 3.85 2.320 18.61  1  1    4    1
# 4    Hornet 4 Drive 21.4   6 0.258 0.110 3.08 3.215 19.44  1  0    3    1
# 5 Hornet Sportabout 18.7   8 0.360 0.175 3.15 3.440 17.02  0  0    3    2
# 6           Valiant 18.1   6 0.225 0.105 2.76 3.460 20.22  1  0    3    1

进一步证明&不是短路。

mymean <- function(x, ...) {
  if (is.character(x)) {
    message("character?")
    return(Inf) # this is certainly not the right thing to do in general ...
  } else mean(x, ...)
}
mtcars %>%
  rownames_to_column("modelle") %>%
  mutate_if(~is.numeric(.x) & mymean(.x) > 50, ~(.x / 1000)) %>%
  head()
# character?
#             modelle  mpg cyl  disp    hp drat    wt  qsec vs am gear carb
# 1         Mazda RX4 21.0   6 0.160 0.110 3.90 2.620 16.46  0  1    4    4
# 2     Mazda RX4 Wag 21.0   6 0.160 0.110 3.90 2.875 17.02  0  1    4    4
# 3        Datsun 710 22.8   4 0.108 0.093 3.85 2.320 18.61  1  1    4    1
# 4    Hornet 4 Drive 21.4   6 0.258 0.110 3.08 3.215 19.44  1  0    3    1
# 5 Hornet Sportabout 18.7   8 0.360 0.175 3.15 3.440 17.02  0  0    3    2
# 6           Valiant 18.1   6 0.225 0.105 2.76 3.460 20.22  1  0    3    1

如果发生短路,则永远mymean不会收到消息。(我认为这mymean不是一个可行的替代品,原因有两个:(1)使用Inf只是为了确保调用工作之外mean的条件,但如果发生错误/警告并且numeric预期会出现 a,那么通常应该返回NAor NaN,而不是数字......即使您可能不考虑Inf真正可用的数字。(2)它解决的是症状,而不是问题。问题是向量化逻辑表达式中没有短路.)


推荐阅读