我有50多个专栏,研究了各种解决方案,包括this。
但是,这并不能真正回答我的问题。我有诸如以下的列名:
total_2012Q1, total_2012Q2, total_2012Q3, total_2012Q4
,...,最多total_2014Q4
,以及其他字符变量。我想按年添加行,所以最后,我将有三年的列:total_2012, total_2013, total_2014
。
我不想rowsum并选择.. sample[,2:5]
之类的内容。有没有一种方法可以对它们求和而无需手动查看列号?另外,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
可复制的示例(帖子):
id total_2012 total_2013 char1 char2
1 6686 3970 N Y
2 5187 1217 Y N
谢谢您的建议。
答案 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_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")
进行收集,而不是使用硬编码的列名或列位置,可以使您扩展到具有更多列的更大数据集。