【问题标题】:tidyverse divide several columns by other columns n positions later (avoiding loops)tidyverse 将几列除以 n 个位置后的其他列(避免循环)
【发布时间】:2019-12-09 18:00:49
【问题描述】:
library(tidyverse)
dat <- tribble(
  ~Scenario,     ~V1,    ~V2,    ~V3,    ~V4,
  1,    0.97,   0.46,   0.79,   0.25,
  1,    0.21,   0.45,   0.23,   0.63,
  1,    0.95,   0.97,   0.07,   0.61,
  1,    0.93,   0.79,   0.23,   0.86,
  2,    0.22,   0.01,   0.42,   0.47,
  2,    0.71,   0.17,   0.16,   0.88,
  3,    0.73,   0.38,   0.10,   0.77,
  3,    0.49,   0.37,   0.90,   0.52,
  3,    0.99,   0.71,   0.66,   0.05,
  3,    0.72,   0.75,   0.69,   0.01,
  3,    0.15,   0.87,   0.12,   0.02,
  4,    0.94,   0.30,   0.91,   0.99)

我正在向该数据添加四个新列,其中每个新列代表按场景分组的每个 V1:V4 列的总和:

dat_new <- dat %>%
  group_by(Scenario) %>%
  mutate_at(vars(-group_cols()), .funs = list(sum = sum))

我正在寻找一种简单的方法来将 V1 除以 V1_sum、V2 除以 V2_sum 等等,假设 a)我有与 sum 列一样多的原始 v 列,并且 b)数据正确排序并遵循我的模式,我首先有我的所有 v 列,然后是 sum 列。

我刚刚在这里问了另一个关于 SO 的问题,重点是将数据转换为长格式,然后将其转换回宽格式,但我想知道在 tidyverse 中是否有更简单的解决方案。

注意:我可能只是循环遍历每一列,然后将其除以列 4 位置,但我正在寻找更优雅的解决方案。

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    我们可以扩展list里面的函数,而不是创建临时的sum列然后分割

    library(dplyr)
    dat %>% 
       group_by(Scenario) %>% 
       mutate_at(vars(-group_cols()), .funs = list(percentage =  ~ ./sum(.)))
    

    如果来自dat_new,一个选项是map

    library(purrr)
    map2_dfc(dat %>% 
                 select(V1:V4), 
            dat_new %>% 
                 ungroup %>%
                 select(ends_with('sum')), `/`)
    

    或使用base R

    dat[2:5]/dat_new[6:9]
    

    【讨论】:

      猜你喜欢
      • 2021-08-12
      • 1970-01-01
      • 2021-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 2015-05-21
      相关资源
      最近更新 更多