Суммируйте только числовые столбцы и делите значения на сумму - PullRequest
1 голос
/ 23 июня 2019

У меня проблемы с некоторыми вычислениями на фрейме данных.

Вот мой DF (с большим количеством строк и столбцов)

Я пытаюсь сделать следующее:

Шаг (1) - За каждый месяц, который я хотел быСуммируйте столбцы активов.Например, все assets_Jan_2018 и вывод в виде DF.

Step (2) - Затем для каждой фирмы я хотел бы разделить активы каждый месяц на общую сумму за месяц, то есть значения, рассчитанные в шаге (1).Например, Фирма A Jan_2018 = 210234/1466742 = 0,14334

Шаг (3) - Затем я хотел бы взять значения из шага (2) и умножить на соответствующие возвраты.= 0.143334 * 4.5 = 0.645003

Шаг (4) - Наконец, я хотел бы суммировать каждый столбец на шаге (3) и вывести в виде DF

 Firm   Assets_Jan_2018  Assets_ Feb_2018 Returns_Jan_2018 Returns_Feb_2018
 A          210234             235425           4.5            6.7
 B          123144             127124           5.3            1.2
 c          897897             789798           1.4            6.2
 D          235467             897342           9.7            3.2

Я пробовал colSums и многиедругие вещи, но продолжали получать сообщения об ошибках.

Ответы [ 2 ]

3 голосов
/ 23 июня 2019

Мы можем сначала разделить столбцы "Assets" и "Returns", а затем использовать colSums и умножить значения соответственно

asset_col <- grep("^Assets", names(df1))
return_col <- grep("^Returns", names(df1))
colSums(t(t(df1[asset_col])/colSums(df1[asset_col])) * df1[return_col])

#Returns_Jan_2018 Returns_Feb_2018 
#        3.504230         4.633941 

Чтобы разбить его и очистить каждый шаг

Шаг 1 - Для каждого месяца я хотел бы суммировать столбцы активов

colSums(df1[asset_col])
#Assets_Jan_2018 Assets_Feb_2018 
#    1466742         2049689 

Шаг 2 - Для каждой фирмы я хотел бы делить активы каждый месяц на общую сумму за месяц

t(t(df1[asset_col])/colSums(df1[asset_col]))
#     Assets_Jan_2018 Assets_Feb_2018
#[1,]      0.14333400      0.11485889
#[2,]      0.08395751      0.06202112
#[3,]      0.61217106      0.38532577
#[4,]      0.16053744      0.43779422

Шаг 3 - Затем я хотел бы взять значения из шага (2) и умножить на соответствующие результаты

t(t(df1[asset_col])/colSums(df1[asset_col])) * df1[return_col]

#  Returns_Jan_2018 Returns_Feb_2018
#1        0.6450030       0.76955455
#2        0.4449748       0.07442534
#3        0.8570395       2.38901980
#4        1.5572131       1.40094151

Шаг 4 - Я хотел бы суммировать каждый столбец на шаге (3))

colSums(t(t(df1[asset_col])/colSums(df1[asset_col])) * df1[return_col])

#Returns_Jan_2018 Returns_Feb_2018 
#        3.504230         4.633941 
1 голос
/ 23 июня 2019

Вероятно, намного менее лаконичен, чем ответ Ронака, но демонстрирует функциональность развертки.

Пример построения df:

df <- data.frame(cbind(Firm = c("A", "B", "C", "D"),
                       Assets_Jan_2018 = as.numeric(c(210234, 123144, 897897, 235467)),
                       Assets_Feb_2018 = as.numeric(c(235425, 127124, 789798, 897342)),
                       Returns_Jan_2018 = as.double(c(4.5,  5.3,  1.4, 9.7)),
                       Returns_Feb_2019 = as.double(c(6.7, 1.2, 6.2, 3.2))))

Убедитесь, что числовые типы данных:

df <- type.convert(df)

Рассчитать взвешенную доходность:

FirmWeightedReturns <- cbind(Firm = df$Firm,
                             sweep(df[sapply(df, is.numeric) & !(grepl("returns", tolower(colnames(df))))],
                                   2,
                                   as.numeric(sapply(df[sapply(df, is.numeric) & !(grepl("returns", tolower(colnames(df))))], sum)), '/')
                                  * df[grepl("returns", tolower(colnames(df)))])

Суммируйте как df:

TotalReturns <- data.frame(lapply(FirmWeightedReturns[sapply(FirmWeightedReturns, is.numeric)], sum))

Вывод на консоль:

TotalReturns
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...