我有一个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