This is an option with dplyr
, but it's a little clunky. The trickiness comes from the fact that you're not cleanly cutting the ID into mutually-exclusive groups, so you need to operate with essentially separate data frames, then bind them back together.
First you need your rownames to be numeric, so you can compare number ranges.
You'll filter the data for the groups of IDs; dplyr::between
is a utility function for finding whether a number is in a range, inclusive of the range's endpoints. I'm adding a variable with mutate
to specify which group data comes from; if you don't need that spelled out, you can drop the mutate
s and just add a .id
argument in bind_rows
. You just will need some way of differentiating the groups for when you summarize.
This goes inside a bind_rows
call, which is like rbind
but can take more than 2 data frames at once. Then group_by
and summarize. If you have too many columns and naming them in summarise_at
becomes cumbersome, you could instead drop the ID and use summarise_all
or summarise_if
.
library(dplyr)
df$id <- as.numeric(row.names(df))
bind_rows(
df %>% filter(between(id, -1, 1)) %>% mutate(group = "-1 to 1"),
df %>% filter(between(id, -2, 1)) %>% mutate(group = "-2 to 1")
) %>%
group_by(group) %>%
summarise_at(vars(GIVN:GFIP), sum)
#> # A tibble: 2 x 4
#> group GIVN MICP GFIP
#> <chr> <dbl> <dbl> <dbl>
#> 1 -1 to 1 -0.03 0.01 0
#> 2 -2 to 1 -0.02 0.03 0.01
Created on 2018-12-17 by the reprex package (v0.2.1)