将函数应用于R中许多列的子集

时间:2018-10-23 03:26:44

标签: r dplyr tidyverse purrr

如何将函数应用于分组行的许多列?例如;

library(tidyverse)
data <- tribble(
  ~Date,      ~Seq1, ~Component, ~Seq2,  ~X1,  ~X2,   ~X3,   
  "01/01/18", 1,     "Smooth",   NA,     3.98,  2.75,  1.82, 
  "01/01/18", 2,     "Smooth",   NA,     1.02,  0.02, -0.04, 
  "01/01/18", 3,     "Smooth",   NA,     3.48,  3.06,  1.25, 
  "01/01/18", 3,     "Bounce",   1,      2.01, -0.43, -0.52, 
  "01/01/18", 3,     "Bounce",   2,      1.94,  1.53,  1.92) %>%
mutate_at(vars(Date, Seq1, Component, Seq2), funs(factor))

每个 X 值列(更多列,为清楚起见在此处被截断)分为 Date Seq1 组件 Seq2 。虽然 Component “平滑”和 Seq1 “ NA”是恒定的,但在 Component “反弹”级别内,存在多个 Seq2 等级,例如“ 1”,“ 2”等

如何对每个 X 列求和,对每个级别的 Seq2 始终为常数“ NA”?

所需的结果是:

expected <- tribble(
~Date,      ~Seq1, ~Component, ~Seq2,  ~X1,  ~X2,   ~X3,   
"01/01/18", 1,     "Smooth",   NA,     3.98,  2.75,  1.82, 
"01/01/18", 2,     "Smooth",   NA,     1.02,  0.02, -0.04, 
"01/01/18", 3,     "Smooth",   NA,     3.48,  3.06,  1.25, 
"01/01/18", 3,     "Bounce",   1,      5.49,  3.49,  1.77, 
"01/01/18", 3,     "Bounce",   2,      5.42,  4.59,  3.17)

以下示例仅添加每个Seq1级别。

data %>% 
  group_by(Date, Seq1) %>%
  mutate_at(vars(starts_with("X")), funs(sum(.)))
#> # A tibble: 5 x 7
#> # Groups:   Date, Seq1 [3]
#>   Date     Seq1  Component  Seq2    X1    X2    X3
#>   <fct>    <fct> <fct>     <fct> <dbl> <dbl> <dbl>
#> 1 01/01/18 1     Smooth    <NA>   3.98  2.75  1.82
#> 2 01/01/18 2     Smooth    <NA>   1.02  0.02 -0.04
#> 3 01/01/18 3     Smooth    <NA>   7.43  4.16  2.65
#> 4 01/01/18 3     Bounce    1      7.43  4.16  2.65
#> 5 01/01/18 3     Bounce    2      7.43  4.16  2.65

我敢肯定purrrapply函数族中有解决方案,但是,在解决此示例方面,我一直失败了好几天。实际数据大约有180个 X 列,具有数百个 Date Seq1 组合,以及多个 Seq2 级别。

一个类似的例子可能是Summing Multiple Groups of ColumnsHow to apply a function to a subset of columns in r?,甚至是https://github.com/jennybc/row-oriented-workflows

reprex package(v0.2.1)于2018-10-23创建

1 个答案:

答案 0 :(得分:0)

这是我的解决方案。这个问题实际上不是purrr任务,因为您实际上没有想要将单个函数映射到的问题。相反,我理解的问题是,您要将X行中的每个Bounce值与相同{{ 1}}和Smooth(并且只有这样一行)。这意味着这确实是一个合并或联接问题,然后该方法是建立联接,以便您可以匹配正确的值并进行求和。因此,我进行如下操作:

  1. 将数据分为X行,Date行和Seq1,以便所有Smooth值都在一列中
  2. Bouncegather连接到X上,因此每个原始smooths行现在都有对应的bounces
  3. left_join总和进入新列,然后选择/重命名列,使其与原始列相同
  4. Bounce加入新求和的Smoothmutate以返回原始布局。

对于任何数量的bind_rowsbouncesspreadDate值,它应该是健壮的。

Seq1

reprex package(v0.2.1)于2018-10-31创建