基于r中的分组或条件的行

时间:2018-12-20 15:55:51

标签: r grouping conditional-statements rowsum

我想根据列名在中进行

我有50多个专栏,研究了各种解决方案,包括this

但是,这并不能真正回答我的问题。我有诸如以下的列名: total_2012Q1, total_2012Q2, total_2012Q3, total_2012Q4,...,最多total_2014Q4,以及其他字符变量。我想按年添加行,所以最后,我将有三年的列:total_2012, total_2013, total_2014

我不想并选择.. sample[,2:5]之类的内容。有没有一种方法可以对它们求和而无需手动查看列号?另外,是一个选项,但是如果也有字符变量,如何只处理要总结的int变量?

简单的可复制示例(上):

id total_2012Q1 total_2012Q2 total_2013Q1 total_2013Q2 char1 char2
 1         1231         5455         1534         2436    N     Y
 2         3948         1239          223          994    Y     N

可复制的示例(帖子):

id total_2012 total_2013 char1 char2
 1       6686      3970     N     Y
 2       5187      1217     Y     N

谢谢您的建议。

2 个答案:

答案 0 :(得分:4)

您可以使用split.default,即

sapply(split.default(df, sub('^.*_([0-9]+)Q[0-9]', '\\1', names(df))), rowSums)
#     2012 2013
#[1,]    3   23
#[2,]    7   37
#[3,]    9   49

数据:

dput(df)
structure(list(total_2012Q1 = c(1, 2, 3), total_2012Q2 = c(2, 
5, 6), total_2013Q1 = c(12, 15, 16), total_2013Q2 = c(11, 22, 
33)), class = "data.frame", row.names = c(NA, -3L))

答案 1 :(得分:1)

我将使用tidyverse函数来实现此目的的方法是将数据重整形为长格式,以使您拥有total_2012Q1total_2012Q2等列。然后可以将其分开分为年份和季度,其中季度被标记为每个字符串的最后两个字符:

library(dplyr)
library(tidyr)

df %>%
  gather(key, value, starts_with("total")) %>%
  separate(key, into = c("year", "quarter"), sep = -2)
#> # A tibble: 8 x 6
#>      id char1 char2 year       quarter value
#>   <dbl> <chr> <chr> <chr>      <chr>   <dbl>
#> 1     1 N     Y     total_2012 Q1       1231
#> 2     2 Y     N     total_2012 Q1       3948
#> 3     1 N     Y     total_2012 Q2       5455
#> 4     2 Y     N     total_2012 Q2       1239
#> 5     1 N     Y     total_2013 Q1       1534
#> 6     2 Y     N     total_2013 Q1        223
#> 7     1 N     Y     total_2013 Q2       2436
#> 8     2 Y     N     total_2013 Q2        994

此后,您可以按标识符和年份分组,对值求和,然后将其重新调整为宽格式。

df %>%
  gather(key, value, starts_with("total")) %>%
  separate(key, into = c("year", "quarter"), sep = -2) %>%
  group_by_at(vars(id:year)) %>%
  summarise(value = sum(value)) %>%
  spread(key = year, value = value)
#> # A tibble: 2 x 5
#> # Groups:   id, char1, char2 [2]
#>      id char1 char2 total_2012 total_2013
#>   <dbl> <chr> <chr>      <dbl>      <dbl>
#> 1     1 N     Y           6686       3970
#> 2     2 Y     N           5187       1217

像这样的方法,特别是使用starts_with("total")进行收集,而不是使用硬编码的列名或列位置,可以使您扩展到具有更多列的更大数据集。