R: calculating column sums & row sums as an aggregation from a dataframe

廉价感情. 提交于 2019-12-02 20:17:39

问题


I am trying to obtain column sums & row sums by aggregating with previous row sums & column sums.

For eg.

My initial data frame is:

      Flag1   Flag2  Flag3   Type1 Type2 Type3
1     Level1    A    FIRST     2     0    0
2     Level1    A    SECOND    1     9    0
3     Level1    A    THIRD     3     7    0
4     Level1    A    FOURTH    9    18    0
5     Level1    A    FIFTH     1    22    0
6     Level1    A    SIXTH     1    13    0
7     Level1    B    FIRST     0     0    0
8     Level1    B    SECOND    3     9    0
9     Level1    B    THIRD     5    85    0
10    Level1    B    FOURTH    4    96    0
11    Level1    B    FIFTH     3    40    0
12    Level1    B    SIXTH     0    17    0
22    Level2    A    FIRST     2     0    0
23    Level2    A    SECOND    1     9    0
24    Level2    A    THIRD     3     7    0
25    Level2    A    FOURTH    9    18    0
26    Level2    A    FIFTH     1    22    0
27    Level2    A    SIXTH     1    13    0
28    Level2    B    FIRST     0     0    0
29    Level2    B    SECOND    3     9    0
30    Level2    B    THIRD     5    85    0
31    Level2    B    FOURTH    4    96    0
32    Level2    B    FIFTH     3    40    0
33    Level2    B    SIXTH     0    17    0
34    Level3    A    FIRST     2     0    0
35    Level3    A    SECOND    1     9    0
36    Level3    A    THIRD     3     7    0
37    Level3    A    FOURTH    9    18    0
38    Level3    A    FIFTH     1    22    0
39    Level3    A    SIXTH     1    13    0
40    Level3    B    FIRST     0     0    0
41    Level3    B    SECOND    3     9    0
42    Level3    B    THIRD     5    85    0
43    Level3    B    FOURTH    4    96    0
44    Level3    B    FIFTH     3    40    0
45    Level3    B    SIXTH     0    17    0

My desired result is:

    Flag1   Flag2   Flag3   Type1   Type2   Type3   Sum
1   Level1  A   FIRST   2   0   0   2
2   Level1  A   SECOND  1   9   0   12
3   Level1  A   THIRD   3   7   0   22
4   Level1  A   FOURTH  9   18  0   49
5   Level1  A   FIFTH   1   22  0   72
6   Level1  A   SIXTH   1   13  0   86
7   Level1  B   FIRST   0   0   0   0
8   Level1  B   SECOND  3   9   0   12
9   Level1  B   THIRD   5   85  0   102
10  Level1  B   FOURTH  4   96  0   202
11  Level1  B   FIFTH   3   40  0   245
12  Level1  B   SIXTH   0   17  0   262
13  Level1  (all)   FIRST   2   0   0   2
14  Level1  (all)   SECOND  4   18  0   24
15  Level1  (all)   THIRD   8   92  0   124
16  Level1  (all)   FOURTH  13  114 0   251
17  Level1  (all)   FIFTH   4   62  0   317
18  Level1  (all)   SIXTH   1   30  0   348
19  Level1  A   (all)   17  68  0   85
20  Level1  B   (all)   15  247 0   262
21  Level1  (all)   (all)   32  315 0   347
22  Level2  A   FIRST   2   0   0   2
23  Level2  A   SECOND  1   9   0   12
24  Level2  A   THIRD   3   7   0   22
25  Level2  A   FOURTH  9   18  0   49
26  Level2  A   FIFTH   1   22  0   72
27  Level2  A   SIXTH   1   13  0   86
28  Level2  B   FIRST   0   0   0   0
29  Level2  B   SECOND  3   9   0   12
30  Level2  B   THIRD   5   85  0   102
31  Level2  B   FOURTH  4   96  0   202
32  Level2  B   FIFTH   3   40  0   245
33  Level2  B   SIXTH   0   17  0   262
34  Level2  (all)   FIRST   2   0   0   2
35  Level2  (all)   SECOND  4   18  0   24
36  Level2  (all)   THIRD   8   92  0   124
37  Level2  (all)   FOURTH  13  114 0   251
38  Level2  (all)   FIFTH   4   62  0   317
39  Level2  (all)   SIXTH   1   30  0   348
40  Level2  A   (all)   17  68  0   85
41  Level2  B   (all)   15  247 0   262
42  Level2  (all)   (all)   32  315 0   347
43  Level3  A   FIRST   2   0   0   2
44  Level3  A   SECOND  1   9   0   12
45  Level3  A   THIRD   3   7   0   22
46  Level3  A   FOURTH  9   18  0   49
47  Level3  A   FIFTH   1   22  0   72
48  Level3  A   SIXTH   1   13  0   86
49  Level3  B   FIRST   0   0   0   0
50  Level3  B   SECOND  3   9   0   12
51  Level3  B   THIRD   5   85  0   102
52  Level3  B   FOURTH  4   96  0   202
53  Level3  B   FIFTH   3   40  0   245
54  Level3  B   SIXTH   0   17  0   262
55  Level3  (all)   FIRST   2   0   0   2
56  Level3  (all)   SECOND  4   18  0   24
57  Level3  (all)   THIRD   8   92  0   124
58  Level3  (all)   FOURTH  13  114 0   251
59  Level3  (all)   FIFTH   4   62  0   317
60  Level3  (all)   SIXTH   1   30  0   348
61  Level3  A   (all)   17  68  0   85
62  Level3  B   (all)   15  247 0   262
63  Level3  (all)   (all)   32  315 0   347
64  (all)   A   FIRST   6   0   0   6
65  (all)   A   SECOND  9   27  0   42
66  (all)   A   THIRD   18  48  0   108
67  (all)   A   FOURTH  45  102 0   255
68  (all)   A   FIFTH   48  168 0   471
69  (all)   A   SIXTH   51  207 0   729
70  (all)   B   FIRST   0   0   0   0
71  (all)   B   SECOND  9   27  0   36
72  (all)   B   THIRD   24  282 0   342
73  (all)   B   FOURTH  36  570 0   948
74  (all)   B   FIFTH   45  690 0   1683
75  (all)   B   SIXTH   45  741 0   2469
76  (all)   A   (all)   51  552 0   1611
77  (all)   B   (all)   45  2310    0   5478
78  (all)   (all)   (all)   96  2862    0   7089

Thanks


回答1:


It's not clear what you want here, since you mention "aggregating" and "previous" enitities, but if you want the rowsums followed by the colsums for a dataframe named dfrm, then this works:

dfrm$totals <- rowSums(dfrm[, 4:6])
dfrmT <- rbind(dfrm, data.frame(Flag1="all", Flag2="all", Flag3="all", 
                                  t( colSums(dfrm[, 4:7]) )
                ) )
dfrmT

EDIT: So you did want the row sums and then within levels of Flag1 and Flag2 you wanted cumsums: (And if you want the multiple subtotals, that was answered in your earlier question.) R: calculating margins or row & col sums for a data frame

dfrmT$CS <- ave(   dfrmT$totals, list(dfrmT$Flag1, dfrmT$Flag2), FUN=cumsum)
dfrmT

     Flag1 Flag2  Flag3 Type1 Type2 Type3 totals  CS
1   Level1     A  FIRST     2     0     0      2   2
2   Level1     A SECOND     1     9     0     10  12
3   Level1     A  THIRD     3     7     0     10  22
4   Level1     A FOURTH     9    18     0     27  49
5   Level1     A  FIFTH     1    22     0     23  72
6   Level1     A  SIXTH     1    13     0     14  86
7   Level1     B  FIRST     0     0     0      0   0
8   Level1     B SECOND     3     9     0     12  12
9   Level1     B  THIRD     5    85     0     90 102
10  Level1     B FOURTH     4    96     0    100 202
11  Level1     B  FIFTH     3    40     0     43 245
12  Level1     B  SIXTH     0    17     0     17 262
22  Level2     A  FIRST     2     0     0      2   2
23  Level2     A SECOND     1     9     0     10  12
24  Level2     A  THIRD     3     7     0     10  22
25  Level2     A FOURTH     9    18     0     27  49
26  Level2     A  FIFTH     1    22     0     23  72
27  Level2     A  SIXTH     1    13     0     14  86
28  Level2     B  FIRST     0     0     0      0   0
29  Level2     B SECOND     3     9     0     12  12
30  Level2     B  THIRD     5    85     0     90 102
31  Level2     B FOURTH     4    96     0    100 202
32  Level2     B  FIFTH     3    40     0     43 245
33  Level2     B  SIXTH     0    17     0     17 262
34  Level3     A  FIRST     2     0     0      2   2
35  Level3     A SECOND     1     9     0     10  12
36  Level3     A  THIRD     3     7     0     10  22
37  Level3     A FOURTH     9    18     0     27  49
38  Level3     A  FIFTH     1    22     0     23  72
39  Level3     A  SIXTH     1    13     0     14  86
40  Level3     B  FIRST     0     0     0      0   0
41  Level3     B SECOND     3     9     0     12  12
42  Level3     B  THIRD     5    85     0     90 102
341    all   all    all    89   795     0    884 884

If on the other hand you want cumsums within each Type with initialization at new Flag1 and Flag2 divisions then:

ave( dfrm[ , grep("Type", names(dfrm))], list(dfrm$Flag1, dfrm$Flag2), FUN=cumsum)
   Type1 Type2 Type3
1      2     0     0
2      3     9     0
3      6    16     0
4     15    34     0
5     16    56     0
6     17    69     0
7      0     0     0
8      3     9     0
9      8    94     0
10    12   190     0
11    15   230     0
12    15   247     0
22     2     0     0
23     3     9     0
24     6    16     0
25    15    34     0
26    16    56     0
27    17    69     0
28     0     0     0
29     3     9     0
30     8    94     0
31    12   190     0
32    15   230     0
33    15   247     0
34     2     0     0
35     3     9     0
36     6    16     0
37    15    34     0
38    16    56     0
39    17    69     0
40     0     0     0
41     3     9     0
42     8    94     0

That is suitable for cbind()-ing to dfrm but needs work on the names():

dfrmCS <- cbind(dfrm, ave( dfrm[ , grep("Type", names(dfrm))], 
                               list(dfrm$Flag1, dfrm$Flag2), FUN=cumsum) )
names(dfrmCS)[8:10] <- paste(names(dfrmCS)[8:10], "CS", sep="_")


来源:https://stackoverflow.com/questions/5982546/r-calculating-column-sums-row-sums-as-an-aggregation-from-a-dataframe

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!