Как создать цикл для расчета суммы, который затем вставляется в новую строку? - PullRequest
0 голосов
/ 01 февраля 2019

Я пытался найти решение с помощью похожих тем, но не нашел ничего подходящего.Это может быть связано с поисковыми терминами, которые я использовал.Если я что-то пропустил, примите мои извинения.

Вот выдержка из моих данных UN_ (предоставленного образца должно быть достаточно):

 country year sector       UN 
      AT 1990      1 1.407555  
      AT 1990      2 1.037137  
      AT 1990      3 4.769618  
      AT 1990      4 2.455139  
      AT 1990      5 2.238618  
      AT 1990  Total 7.869005  
      AT 1991      1 1.484667  
      AT 1991      2 1.001578  
      AT 1991      3 4.625927  
      AT 1991      4 2.515453 
      AT 1991      5 2.702081 
      AT 1991  Total 8.249567 
      ....
      BE 1994      1 3.008115  
      BE 1994      2 1.550344  
      BE 1994      3 1.080667  
      BE 1994      4 1.768645  
      BE 1994      5 7.208295  
      BE 1994  Total 1.526016  
      BE 1995      1 2.958820  
      BE 1995      2 1.571759 
      BE 1995      3 1.116049  
      BE 1995      4 1.888952
      BE 1995      5 7.654881  
      BE 1995  Total 1.547446 
      ....

Что я хочу сделатьесть, чтобы добавить еще одну строку с UN_$sector = Residual.Значение остатка будет (UN_$sector = Total) - (the sum of column UN for the sectors c("1", "2", "3", "4", "5")) для данного года И страны.

Вот как это должно выглядеть:

 country year      sector       UN 
      AT 1990           1 1.407555  
      AT 1990           2 1.037137  
      AT 1990           3 4.769618  
      AT 1990           4 2.455139  
      AT 1990           5 2.238618  
----> AT 1990    Residual TO BE CALCULATED
      AT 1990       Total 7.869005 

Поскольку я не хочу писать много, многоСтроки кода, я ищу способ автоматизировать это.Мне сказали про петли, но на данный момент я не могу следовать концепции.

Большое спасибо за любую помощь !!

Best,

Константин

PS: (для Parfait)

   country year sector        UN ETS
   UK      2012      1 190336512  NA
   UK      2012      2  18107910  NA
   UK      2012      3   8333564  NA
   UK      2012      4  11269017  NA
   UK      2012      5   2504751  NA
   UK      2012  Total 580957306  NA
   UK      2013      1 177882200  NA
   UK      2013      2  20353347  NA
   UK      2013      3   8838575  NA
   UK      2013      4  11051398  NA
   UK      2013      5   2684909  NA
   UK      2013  Total 566322778  NA

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

Сначала рассмотрите возможность вычисления остатка, а затем объедините его с другими частями данных:

# CALCULATE RESIDUALS BY MERGED COLUMNS
agg <- within(merge(aggregate(UN ~ country + year, data = subset(df, sector!='Total'), sum),
                    aggregate(UN ~ country + year, data = subset(df, sector=='Total'), sum),
                    by=c("country", "year")),
             {UN <- UN.y - UN.x
              sector = 'Residual'})

# ROW BIND DIFFERENT PIECES
final_df <- rbind(subset(df, sector!='Total'),
                  agg[c("country", "year", "sector", "UN")],
                  subset(df, sector=='Total'))

# ORDER ROWS AND RESET ROWNAMES
final_df <- with(final_df, final_df[order(country, year, as.character(sector)),])
row.names(final_df) <- NULL

Rextester demo

final_df
#    country year   sector         UN
# 1       AT 1990        1   1.407555
# 2       AT 1990        2   1.037137
# 3       AT 1990        3   4.769618
# 4       AT 1990        4   2.455139
# 5       AT 1990        5   2.238618
# 6       AT 1990 Residual  -4.039062
# 7       AT 1990    Total   7.869005
# 8       AT 1991        1   1.484667
# 9       AT 1991        2   1.001578
# 10      AT 1991        3   4.625927
# 11      AT 1991        4   2.515453
# 12      AT 1991        5   2.702081
# 13      AT 1991 Residual  -4.080139
# 14      AT 1991    Total   8.249567
# 15      BE 1994        1   3.008115
# 16      BE 1994        2   1.550344
# 17      BE 1994        3   1.080667
# 18      BE 1994        4   1.768645
# 19      BE 1994        5   7.208295
# 20      BE 1994 Residual -13.090050
# 21      BE 1994    Total   1.526016
# 22      BE 1995        1   2.958820
# 23      BE 1995        2   1.571759
# 24      BE 1995        3   1.116049
# 25      BE 1995        4   1.888952
# 26      BE 1995        5   7.654881
# 27      BE 1995 Residual -13.643015
# 28      BE 1995    Total   1.547446
0 голосов
/ 01 февраля 2019

Я думаю, что вы можете сделать это несколькими способами.Что я могу порекомендовать, так это воспользоваться пакетом tidyverse, включающим dplyr.

Не вдаваясь слишком далеко в то, чего могут достичь dplyr и tidyverse, мы можем поговорить о силе встроенных команд dplyr group_by(...), summarise(...), arrange(...) и bind_rows(...).Кроме того, существует множество отличных учебных пособий, шпаргалок и документации по всем пакетам tidyverse.

Хотя это все менее и менее актуально в наши дни, мы обычно хотим избегать циклов в R. Поэтому мысоздаст новый фрейм данных, который содержит все остаточные значения, а затем вернет его в исходный фрейм данных.

Шаг 1: Расчет всех остаточных значений

Мы хотимрассчитать сумму значений ООН, сгруппированных по country и year.Мы можем достичь этого с помощью этого значения

res_UN = UN_ %>% group_by(country, year) %>% summarise(UN = sum(UN, na.rm = T))

Шаг 2: Добавить столбец сектора к res_UN со значением 'residual'

Это должно привести кфрейм данных, который содержит country, year и UN, теперь нам нужно добавить столбец sector, значение которого «Остаточное» для удовлетворения ваших требований.

res_UN$sector = 'Residual'

Шаг 3: Добавьте res_UN обратно в UN_ и сделайте соответствующий порядок

res_UN и UN_ теперь имеют одинаковые столбцы, и теперь их можно добавлять обратно.

UN_ = bind_rows(UN_, res_UN) %>% arrange(country, year, sector)

Собирая все это вместе, вы должны ответить на ваш вопрос, и это может быть достигнуто в пару строк!

TLDR:

res_UN = UN_ %>% group_by(country, year) %>% summarise(UN = sum(UN, na.rm = T))`
res_UN$sector = 'Residual'
UN_ = bind_rows(UN_, res_UN) %>% arrange(country, year, sector)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...