【问题标题】:Subtract and divide using one mutate_across function in dplyr使用 dplyr 中的一个 mutate_across 函数进行减法和除法
【发布时间】:2021-07-06 10:59:35
【问题描述】:

我有一个看起来像 iris 数据集的数据集。

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

我想通过 Sepal.Length:Petal.Width 用数字 2 减去每个值,然后将结果除以 4。如何在 dplyr 中使用 mutate_across 而不是两行来做到这一点?

iris %>% 
  mutate(across(c(Sepal.Length:Petal.Width), ~. -2 )) %>% 
  mutate(across(c(Sepal.Length:Petal.Width), ~. /4 )) 

【问题讨论】:

    标签: r dplyr tidyverse across


    【解决方案1】:
    library(dplyr, warn.conflicts = F)
    iris %>%
      mutate(across(1:4, ~  (. - 2)/4))
    #>     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
    #> 1          0.775       0.375       -0.150      -0.450     setosa
    #> 2          0.725       0.250       -0.150      -0.450     setosa
    #> 3          0.675       0.300       -0.175      -0.450     setosa
    #> 4          0.650       0.275       -0.125      -0.450     setosa
    #> 5          0.750       0.400       -0.150      -0.450     setosa
    #> 6          0.850       0.475       -0.075      -0.400     setosa
    #> 7          0.650       0.350       -0.150      -0.425     setosa
    #> 8          0.750       0.350       -0.125      -0.450     setosa
    #> 9          0.600       0.225       -0.150      -0.450     setosa
    #> 10         0.725       0.275       -0.125      -0.475     setosa
    .
    .
    
    

    reprex package (v2.0.0) 于 2021-07-06 创建

    【讨论】:

    • 为什么不能是where(is.numeric)
    • 可以。但 OP 想将代码缩短 1 步。
    【解决方案2】:

    减法和除法函数可以直接应用于数据帧。

    cols <- 1:4
    iris[cols] <- (iris[cols] - 2)/4
    head(iris)
    
    #  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
    #1        0.775       0.375       -0.150       -0.45  setosa
    #2        0.725       0.250       -0.150       -0.45  setosa
    #3        0.675       0.300       -0.175       -0.45  setosa
    #4        0.650       0.275       -0.125       -0.45  setosa
    #5        0.750       0.400       -0.150       -0.45  setosa
    #6        0.850       0.475       -0.075       -0.40  setosa
    

    【讨论】:

    • 谢谢罗纳克。一如既往的整洁解决方案
    【解决方案3】:

    另一种解决方案是使用mutate_at

    iris %>%
      mutate_at(vars('Sepal.Length':'Petal.Width'), funs((. - 2) * 4))
    

    【讨论】:

    • 请注意,_if_at_all 已在 dplyr 中被正式“取代”(略弱于弃用),我们鼓励您改用 across()。请参阅vignette("colwise"):“这些功能解决了一个紧迫的需求并被许多人使用,但现在已被取代。这意味着它们将继续存在,但不会收到任何新功能,只会得到关键的错误修复。”
    【解决方案4】:

    map_if 的选项

    library(purrr)
    library(dplyr)
    map_if(iris, is.numeric, ~ (. - 2)/4) %>%
         bind_cols
    

    【讨论】:

      【解决方案5】:

      我们可以试试下面的 base R 选项

      cols <- which(sapply(iris, is.numeric))
      iris[cols] <- (iris[cols] - 2) / 4
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-15
        • 2021-03-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 1970-01-01
        相关资源
        最近更新 更多