【问题标题】:R mutate_if rounding issueR mutate_if 舍入问题
【发布时间】:2021-03-31 16:37:11
【问题描述】:

我有一个包含几个字符列和许多数字列的数据框。我需要用1替换所有大于1的列中的所有数值,而不修改字符列。 我使用 mutate_if 来实现我的目标,但我面临的问题是它会自动舍入数据,我不希望这样。我怎样才能避免四舍五入? 这是我的示例代码:

mtcars$TEXT <- rownames(mtcars)
mtcars %>% mutate_if(is.numeric, ~4.00 * (. > 4))

如果您打印它,您会注意到所有值现在都是 4 或 0。 我真的很困惑,不知道为什么。 谢谢

【问题讨论】:

  • 使用ifelse:mutate_if(is.numeric, ~ifelse(. &gt; 1, 1, .))
  • 你为什么使用 4 ?问题是将大于 1 替换为 1,但您正在做其他事情。
  • pmin ......
  • @bouncyball 您的解决方案效果很好。谢谢

标签: r dplyr tidyverse


【解决方案1】:

编辑:感谢 Gregor Thomas 和社区的反馈: 这是修改后的版本:

library(dplyr)
# old solution
# mtcars %>%  mutate(across(where(is.numeric), ~case_when(is.numeric(.) & . > 1 ~ 1, TRUE ~ .)))

# new solution implementing the advice of Gregor Thomas and Hong Ooi
mtcars %>% mutate(across(where(is.numeric), pmin, 1))

数据:

mtcars$TEXT <- rownames(mtcars)
mtcars %>% mutate_if(is.numeric, ~4.00 * (. > 4))

输出:

                    mpg cyl disp hp drat wt qsec vs am gear carb                TEXT
Mazda RX4             1   1    1  1    1  1    1  0  1    1    1           Mazda RX4
Mazda RX4 Wag         1   1    1  1    1  1    1  0  1    1    1       Mazda RX4 Wag
Datsun 710            1   1    1  1    1  1    1  1  1    1    1          Datsun 710
Hornet 4 Drive        1   1    1  1    1  1    1  1  0    1    1      Hornet 4 Drive
Hornet Sportabout     1   1    1  1    1  1    1  0  0    1    1   Hornet Sportabout
Valiant               1   1    1  1    1  1    1  1  0    1    1             Valiant
Duster 360            1   1    1  1    1  1    1  0  0    1    1          Duster 360
Merc 240D             1   1    1  1    1  1    1  1  0    1    1           Merc 240D
Merc 230              1   1    1  1    1  1    1  1  0    1    1            Merc 230
Merc 280              1   1    1  1    1  1    1  1  0    1    1            Merc 280
Merc 280C             1   1    1  1    1  1    1  1  0    1    1           Merc 280C
Merc 450SE            1   1    1  1    1  1    1  0  0    1    1          Merc 450SE
Merc 450SL            1   1    1  1    1  1    1  0  0    1    1          Merc 450SL
Merc 450SLC           1   1    1  1    1  1    1  0  0    1    1         Merc 450SLC
Cadillac Fleetwood    1   1    1  1    1  1    1  0  0    1    1  Cadillac Fleetwood
Lincoln Continental   1   1    1  1    1  1    1  0  0    1    1 Lincoln Continental
Chrysler Imperial     1   1    1  1    1  1    1  0  0    1    1   Chrysler Imperial
Fiat 128              1   1    1  1    1  1    1  1  1    1    1            Fiat 128
Honda Civic           1   1    1  1    1  1    1  1  1    1    1         Honda Civic
Toyota Corolla        1   1    1  1    1  1    1  1  1    1    1      Toyota Corolla
Toyota Corona         1   1    1  1    1  1    1  1  0    1    1       Toyota Corona
Dodge Challenger      1   1    1  1    1  1    1  0  0    1    1    Dodge Challenger
AMC Javelin           1   1    1  1    1  1    1  0  0    1    1         AMC Javelin
Camaro Z28            1   1    1  1    1  1    1  0  0    1    1          Camaro Z28
Pontiac Firebird      1   1    1  1    1  1    1  0  0    1    1    Pontiac Firebird
Fiat X1-9             1   1    1  1    1  1    1  1  1    1    1           Fiat X1-9
Porsche 914-2         1   1    1  1    1  1    1  0  1    1    1       Porsche 914-2
Lotus Europa          1   1    1  1    1  1    1  1  1    1    1        Lotus Europa
Ford Pantera L        1   1    1  1    1  1    1  0  1    1    1      Ford Pantera L
Ferrari Dino          1   1    1  1    1  1    1  0  1    1    1        Ferrari Dino
Maserati Bora         1   1    1  1    1  1    1  0  1    1    1       Maserati Bora
Volvo 142E            1   1    1  1    1  1    1  1  1    1    1          Volvo 142E

【讨论】:

  • 我认为上面的解决方案仍然存在同样的问题。数据不满足条件的地方设置为0。你看到了吗?
  • 你的意思是TRUE ~ . 吗?请查看我的编辑。
  • 请使用mutate_across() 这些助手已被弃用:mutate_if.(.df, .predicate, .funs, ..., .by = NULL); mutate_at.(.df, .vars, .funs, ..., .by = NULL); mutate_all.(.df, .funs, ..., .by = NULL)。 bouncyball 的解决方案提供与我编辑的版本相同的输出。不客气!
  • 既然你有where(is.numeric),那么is.numeric(.)里面的case_when检查是多余的。您可以稍微简化为mutate(across(where(is.numeric), ~case_when(. &gt; 1 ~ 1,TRUE ~ .))),或者将pmin 建议简化为mutate(across(where(is.numeric), pmin, 1))
  • @TarJae 感谢您迄今为止的帮助,感谢您对此进行调查。您的最后一个解决方案与 Gregor Thomas 共享的解决方案一样有效
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-19
  • 2013-04-12
  • 2011-08-23
  • 2011-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多