r-突变(在ON ON ON上应用)几个不同尺寸的柱子集(包含矢量中的模式),并在DPLYR中自动命名



我有一个data.frame如下:

df = data.frame(a1 = c(1:6, rep(NA,6)),
                a2 = c(rep(NA,6), 7:12),
                b1 = rep(c(1,NA), 6),
                b2 = rep(c(NA,2), 6),
                c1 = rep(c(1,NA,NA), each=4),
                c2 = rep(c(NA,2,NA), each=4),
                c3 = rep(c(NA,NA,3), each=4))
#    a1 a2 b1 b2 c1 c2 c3
# 1   1 NA  1 NA  1 NA NA
# 2   2 NA NA  2  1 NA NA
# 3   3 NA  1 NA  1 NA NA
# 4   4 NA NA  2  1 NA NA
# 5   5 NA  1 NA NA  2 NA
# 6   6 NA NA  2 NA  2 NA
# 7  NA  7  1 NA NA  2 NA
# 8  NA  8 NA  2 NA  2 NA
# 9  NA  9  1 NA NA NA  3
# 10 NA 10 NA  2 NA NA  3
# 11 NA 11  1 NA NA NA  3
# 12 NA 12 NA  2 NA NA  3

在这里,有3组列,每个列中包含一个名称中的模式(2个带有a、2个带有b的Cols的Cols,带有c的COLS(,我需要在这些子集上应用一个操作以总结每个操作它们在单列中(以通用模式命名( - 在此,只需合并它们以删除Na的删除即可。

我可以使用基本r进行以下操作:

sapply(c('a', 'b', 'c'), function(x) rowSums(df[,grepl(x, names(df))], na.rm=T))
#       a b c
# [1,]  1 1 1
# [2,]  2 2 1
# [3,]  3 1 1
# [4,]  4 2 1
# [5,]  5 1 2
# [6,]  6 2 2
# [7,]  7 1 2
# [8,]  8 2 2
# [9,]  9 1 3
# [10,] 10 2 3
# [11,] 11 1 3
# [12,] 12 2 3

但是我不知道如何在dplyr中进行操作?我想通过mutate_each_select(contains())等的一些智能组合,但我无法理解... ??

可能有许多列子集,我需要一个完全自动的解决方案,我只给出模式向量(此处,c('a','b','c')((即,我不想手动命名输出列(。

我们可以在tidyverse软件包(purrr(中使用split CC_11 ting数据集在没有数字的列名(sub(...)(

的情况下执行此操作。
library(tidyverse)
split.default(df, sub("\d+", "", names(df))) %>% 
                      map_df(~rowSums(., na.rm = TRUE))
#     A tibble: 12 × 3
#       a     b     c
#   <dbl> <dbl> <dbl>
#1      1     1     1
#2      2     2     1
#3      3     1     1
#4      4     2     1
#5      5     1     2
#6      6     2     2
#7      7     1     2
#8      8     2     2
#9      9     1     3
#10    10     2     3
#11    11     1     3
#12    12     2     3

一般的平淡解决方案可能要求您首先重塑。不幸的是,我们必须在此操作过程中跟踪行,这很大。

patterns <- c('a', 'b', 'c')
df %>% 
  mutate(i = row_number()) %>% 
  gather(key, value, -i) %>% 
  mutate(group = do.call(coalesce, purrr::map(patterns, ~stringr::str_match(tmp$key, .)))) %>% 
  group_by(group, i) %>% 
  summarise(value = sum(value, na.rm = TRUE)) %>% 
  spread(group, value) %>% 
  select(-i)

给出:

# A tibble: 12 × 3
       a     b     c
*  <dbl> <dbl> <dbl>
1      1     1     1
2      2     2     1
3      3     1     1
4      4     2     1
5      5     1     2
6      6     2     2
7      7     1     2
8      8     2     2
9      9     1     3
10    10     2     3
11    11     1     3
12    12     2     3

您可以通过更改summarise语句中的隔离来对原始行执行任何任意操作。它也概括为任何任意模式。

您可以可能使用SE范式直接编码适当的transmute函数,但是我无法确切地弄清楚如何(使用即将到来的dplyr 0.6.0(。单个模式的开始:

patterns <- c('a', 'b', 'c')
cols <- map(patterns, ~map(grep(., names(df), value = TRUE), rlang::as_symbol))
transmute(df, !!patterns[1] := coalesce(!!!cols[[1]]))

给出:

    a
1   1
2   2
3   3
4   4
5   5
6   6
7   7
8   8
9   9
10 10
11 11
12 12

最新更新