rowsum 基于 r 中的分组或条件
rowsum based on groupings or conditions in r
我有 50 多个专栏并且查看了各种解决方案,包括 this。
但是,这并没有真正回答我的问题。我有列名,例如:
total_2012Q1, total_2012Q2, total_2012Q3, total_2012Q4
,..., 最多 total_2014Q4
和其他字符变量。我想按年添加行,所以最后,我将有三年的列:total_2012, total_2013, total_2014
。
我不想rowsum and select something like ..sample[,2:5]
. Is there a way I can sum them without manually going through column numbers? Also, split.default是一个选项,但是如果还有字符变量,你如何只处理你想要总结的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
可重现的例子(post):
id total_2012 total_2013 char1 char2
1 6686 3970 N Y
2 5187 1217 Y N
感谢您的任何建议。
您可以使用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))
我使用 tidyverse
函数处理此问题的方法是将数据重塑为长格式,这样您就有了 total_2012Q1
、total_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")
进行收集而不是硬编码列名或列位置,可以让您扩展到包含更多列的更大数据集。
我有 50 多个专栏并且查看了各种解决方案,包括 this。
但是,这并没有真正回答我的问题。我有列名,例如:
total_2012Q1, total_2012Q2, total_2012Q3, total_2012Q4
,..., 最多 total_2014Q4
和其他字符变量。我想按年添加行,所以最后,我将有三年的列:total_2012, total_2013, total_2014
。
我不想rowsum and select something like ..sample[,2:5]
. Is there a way I can sum them without manually going through column numbers? Also, split.default是一个选项,但是如果还有字符变量,你如何只处理你想要总结的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
可重现的例子(post):
id total_2012 total_2013 char1 char2
1 6686 3970 N Y
2 5187 1217 Y N
感谢您的任何建议。
您可以使用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))
我使用 tidyverse
函数处理此问题的方法是将数据重塑为长格式,这样您就有了 total_2012Q1
、total_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")
进行收集而不是硬编码列名或列位置,可以让您扩展到包含更多列的更大数据集。