【问题标题】:How to programmatically calculate the difference between a pair of variables using dplyr?如何使用 dplyr 以编程方式计算一对变量之间的差异?
【发布时间】:2021-09-29 15:13:17
【问题描述】:

假设我有一个像下面这样的小标题:

tib <- tribble(~id, ~var1_countrya, ~var2_countrya, ~var1_countryb, ~var2_countryb,
1, 1, 2, 1, 2,
2, 5, 3, 1, 3,
3, 6, 3, 1, 3
)

我想通过使用正则表达式和 dplyr 管道选择变量对来创建新列 delta_countrya = var2_countrya - var1_countryadelta_countryb = var2_countryb - var2_countryb。最后的 tibble 应该是这样的

id var1_countrya var2_countrya delta_countrya var1_countryb var2_countryb delta_countryb
1             1             2              1             1             2              1
2             5             3             -2             1             3              2
3             6             3             -3             1             3              2

我什至很难以一种创建多个新变量的方式设置 mutate 子句,更不用说找到我正在寻找的变量对并从中获取差异了。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    base

    tib[paste0("delta_country", letters[1:2])] <- tib[paste0("var2_country", letters[1:2])] - tib[paste0("var1_country", letters[1:2])]
        #      id var1_countrya var2_countrya var1_countryb var2_countryb delta_countrya delta_countryb
        #   <dbl>         <dbl>         <dbl>         <dbl>         <dbl>          <dbl>          <dbl>
        # 1     1             1             2             1             2              1              1
        # 2     2             5             3             1             3             -2              2
        # 3     3             6             3             1             3             -3              2
    

    tidyverse

    library(tidyverse)
    tib[paste0("delta_country", letters[1:2])] <- map2(tib %>% select(starts_with("var2_country")), tib %>% select(starts_with("var1_country")),
                                         ~.x - .y)
    tib
    # #      id var1_countrya var2_countrya var1_countryb var2_countryb delta_countrya delta_countryb
    # #   <dbl>         <dbl>         <dbl>         <dbl>         <dbl>          <dbl>          <dbl>
    # # 1     1             1             2             1             2              1              1
    # # 2     2             5             3             1             3             -2              2
    # # 3     3             6             3             1             3             -3              2
    

    【讨论】:

      【解决方案2】:

      通过您的示例,您可以将列转换为变量,拆分列,使 var 和国家/地区分开,然后重新组合,使不同的 var 在列中,最后计算您的增量

      library(dplyr) 
      tib <- tribble(~id, ~var1_countrya, ~var2_countrya, ~var1_countryb, ~var2_countryb,
      1, 1, 2, 1, 2,
      2, 5, 3, 1, 3,
      3, 6, 3, 1, 3
      )  # your code had an error, need to replace ')' with comma
      
      tib2 = tib %>%
            pivot_longer(-id, names_to = "var") %>%
            separate(var, c("Var", "Country")) %>%
            pivot_wider(names_from = Var) %>%
            mutate(Delta = var2-var1)
      tib2
      # # A tibble: 6 x 5
      #      id Country   var1  var2 Delta
      #    <dbl> <chr>    <dbl> <dbl> <dbl>
      # 1     1 countrya     1     2     1
      # 2     1 countryb     1     2     1
      # 3     2 countrya     5     3    -2
      # 4     2 countryb     1     3     2
      # 5     3 countrya     6     3    -3
      # 6     3 countryb     1     3     2
      

      【讨论】:

      • 太棒了,这就像一个魅力。显然,然后我们需要 pivot_wider 来获得最终的 tibble。
      【解决方案3】:

      我们也可以在这里利用base::Reduce

      Reduce(function(x, y) {
        cbind(x, x[, y] - x[, y - 1])
      }, seq(1, ncol(tib), 2)[-1], init = tib) |>
        setNames(c(names(tib), paste0("delta_country", unique(gsub(".*([[:alpha:]]$)", "\\1", names(tib)[-1])))))
      
        id var1_countrya var2_countrya var1_countryb var2_countryb delta_countrya delta_countryb
      1  1             1             2             1             2              1              1
      2  2             5             3             1             3             -2              2
      3  3             6             3             1             3             -3              2
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-22
        • 2023-02-21
        相关资源
        最近更新 更多