【问题标题】:apply function or loop within mutate在 mutate 中应用函数或循环
【发布时间】:2022-01-12 21:56:51
【问题描述】:

假设我有一个数据框。我想通过减去每对现有列来改变新列。匹配列中有规则。例如,在下面的代码中,减法的第一个组件 (base_g00) 的前缀都是相同的,而第二个组件 (allow_m00) 的前缀是相同的。此外,第一个组件的 id 编号为 27 到 43,第二个组件的 id 为 20 到 36,也可以解释为 (1st_id-7)。我想知道下面的代码,我可以用 apply 函数或 mutate 格式的循环来编写代码以使代码更简单。非常感谢您提前提出任何建议!

pred_error<-y07_13%>%mutate(annual_util_1=base_g0027-allow_m0020,
     annual_util_2=base_g0028-allow_m0021,
     annual_util_3=base_g0029-allow_m0022,
     annual_util_4=base_g0030-allow_m0023,
     annual_util_5=base_g0031-allow_m0024,
     annual_util_6=base_g0032-allow_m0025,
     annual_util_7=base_g0033-allow_m0026,
     annual_util_8=base_g0034-allow_m0027,
     annual_util_9=base_g0035-allow_m0028,
     annual_util_10=base_g0036-allow_m0029,
     annual_util_11=base_g0037-allow_m0030,
     annual_util_12=base_g0038-allow_m0031,
     annual_util_13=base_g0039-allow_m0032,
     annual_util_14=base_g0040-allow_m0033,
     annual_util_15=base_g0041-allow_m0034,
     annual_util_16=base_g0042-allow_m0035,
     annual_util_17=base_g0043-allow_m0036)

【问题讨论】:

  • 请分享一些样本数据来测试解决方案。我们不需要太多,2 或 3 行,2 或 3 列对就足够了。 dput() 是制作您拥有的数据的复制/可粘贴版本的好方法,包括所有类和结构信息。 dput(y07_13[1:4, c("base_g0027", "allow_m0020", "base_g0028", "allow_m0021")]) 非常适合共享前 2 列对的前 4 行。
  • 感谢 Gregor 的建议!

标签: r loops dplyr apply


【解决方案1】:

我认为更惯用的 tidyverse 方法是重塑您的数据,以便将这些列组编码为变量,而不是作为具有相同语义含义的单独列。

例如,

library(dplyr); library(tidyr); library(stringr)       
y07_13 <- tibble(allow_m0021 = 1:5,
                 allow_m0022 = 2:6,
                 allow_m0023 = 11:15,
                 base_g0028 = 5,
                 base_g0029 = 3:7,
                 base_g0030 = 100)

y07_13 %>%
  mutate(row = row_number()) %>%
  pivot_longer(-row) %>%
  mutate(type = str_extract(name, "allow_m|base_g"),
         num = str_remove(name, type) %>% as.numeric(),
         group = num - if_else(type == "allow_m", 20, 27)) %>%
  select(row, type, group, value) %>%
  pivot_wider(names_from = type, values_from = value) %>%
  mutate(annual_util = base_g - allow_m)

结果

# A tibble: 15 x 5
     row group allow_m base_g annual_util
   <int> <dbl>   <dbl>  <dbl>       <dbl>
 1     1     1       1      5           4
 2     1     2       2      3           1
 3     1     3      11    100          89
 4     2     1       2      5           3
 5     2     2       3      4           1
 6     2     3      12    100          88
 7     3     1       3      5           2
 8     3     2       4      5           1
 9     3     3      13    100          87
10     4     1       4      5           1
11     4     2       5      6           1
12     4     3      14    100          86
13     5     1       5      5           0
14     5     2       6      7           1
15     5     3      15    100          85

【讨论】:

  • 这太棒了!谢谢乔恩!!
【解决方案2】:

这里是向量化的基础 R 方法 -

base_cols <- paste0("base_g00", 27:43)
allow_cols <- paste0("allow_m00", 20:36)
new_cols <- paste0("annual_util", 1:17)
y07_13[new_cols] <- y07_13[base_cols] - y07_13[allow_cols]
y07_13

【讨论】:

  • 这很聪明!谢谢罗纳克!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 2015-01-30
  • 2016-10-15
  • 2020-12-03
  • 1970-01-01
相关资源
最近更新 更多