Создать столбцы из агрегированных данных строки в R - PullRequest
0 голосов
/ 30 сентября 2018

У меня есть фрейм данных, который содержит исторические возвраты цен.Данные организованы по столбцам даты и множеству столбцов активов (обозначаются как A1, A2 ...).Каждый столбец актива содержит данные о возврате цены для каждой уникальной исторической даты.Я хотел бы обработать эти данные, чтобы создать фрейм данных со многими столбцами активов и только одной строкой данных - со строкой данных, содержащей агрегированное / среднее число строк для новых столбцов.Новым столбцам нужны заголовки, представляющие собой исходное имя актива, объединенные с информацией о дате.Ниже приведен упрощенный пример исходной даты:

> df <- read.csv("data.csv", header=T)
> df
  Year Month A1 A2 A3
1 2015   Jan  1  1  1
2 2015   Feb  2  2  2
3 2015   Mar  3  3  3
4 2016   Jan  1  1  1
5 2016   Feb  2  2  2
6 2016   Mar  3  3  3

Я использовал простые повторяющиеся числа для возврата.Я использую функцию, которая требует, чтобы данные были организованы следующим образом:

> df2 <- read.csv("data2.csv", header=T)
> df2

  Returns A1.Jan A1.Feb A1.Mar A2.Jan A2.Feb A2.Mar A3.Jan A3.Feb A3.Mar
1 Average      1      2      3      1      2      3      1      2      3

Для ясности, A1.Jan содержит среднее значение всех январских возвратов за год.Заранее благодарим за понимание и / или решение.

Ответы [ 3 ]

0 голосов
/ 30 сентября 2018

Посмотрите на базовую функцию изменить форму.По сути, это та же задача, что и в последнем примере на ее странице справки:

reshape(df, idvar="Year", direction="wide", timevar="Month")
  Year A1.Jan A2.Jan A3.Jan A1.Feb A2.Feb A3.Feb A1.Mar A2.Mar A3.Mar
1 2015      1      1      1      2      2      2      3      3      3
4 2016      1      1      1      2      2      2      3      3      3

Вы хотели, чтобы переменная Year оставалась идентификатором столбца, но вы хотели, чтобы переменная Month действовала как последовательность, которая получаетраспространение "широкий".

0 голосов
/ 01 октября 2018

Вот решение Tidyverse.Я учел месяцы, чтобы их можно было упорядочить, затем использовал tidyr::gather() для преобразования в длинный формат, чтобы я мог dplyr::group_by() по месяцам до dplyr::summarise(), чтобы найти среднее значение:

library(dplyr)
library(tidyr)

df <- read.table(text = "
  Year Month A1 A2 A3
1 2015   Jan  1  1  1
2 2015   Feb  2  2  2
3 2015   Mar  3  3  3
4 2016   Jan  1  1  1
5 2016   Feb  2  2  2
6 2016   Mar  3  3  3", header = T) %>%
  tbl_df()

df$Month <- df$Month %>%
  factor(levels = format(ISOdate(2000, 1:12, 1), "%b"))

df_tidy <- df %>%
  gather(asset, value, -Year, -Month) %>%
  group_by(Month, asset) %>%
  summarise(Average = mean(value)) %>%
  arrange(asset, Month)
df_tidy

# # A tibble: 9 x 3
# # Groups:   Month [3]
#   Month asset Average
#   <fct> <chr>   <dbl>
# 1 Jan   A1          1
# 2 Feb   A1          2
# 3 Mar   A1          3
# 4 Jan   A2          1
# 5 Feb   A2          2
# 6 Mar   A2          3
# 7 Jan   A3          1
# 8 Feb   A3          2
# 9 Mar   A3          3


# convert to wide format, as in OP - not sure of 'easy' way
# to order columns by asset.month other than using 'select()'
# (it currently sorts alphabetically).

df_tidy %>%
  unite(Returns, c(asset, Month), sep = ".") %>%
  spread(Returns, Average)

# # A tibble: 1 x 9
#   A1.Feb A1.Jan A1.Mar A2.Feb A2.Jan A2.Mar A3.Feb A3.Jan A3.Mar
#    <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
# 1      2      1      3      2      1      3      2      1      3
0 голосов
/ 30 сентября 2018

С помощью data.table вы можете сделать

library(data.table)
setDT(df)
df[, lapply(.SD, mean), .SDcols = names(df)[grep("^A", names(df))], by = Month
   ][, Returns := "Average"
     ][, melt(.SD, id = c("Month", "Returns"))
       ][, dcast(.SD, Returns ~ variable + Month, value.var = 'value', sep = ".")]

#   Returns A1.Feb A1.Jan A1.Mar A2.Feb A2.Jan A2.Mar A3.Feb A3.Jan A3.Mar
#1: Average      2      1      3      2      1      3      2      1      3

. В первой строке мы агрегируем данные по Month.Часть names(df)[grep("^A", names(df)) гарантирует, что мы агрегируем только те переменные, которые начинаются с буквы «А».

Во второй строке создается переменная Returns, которая содержит значение «Среднее».

melt собирает ваши данные в длинном формате, и dcast в конце концов распространяется на требуемый вывод.

данные

df <- structure(list(Year = c(2015L, 2015L, 2015L, 2016L, 2016L, 2016L
), Month = c("Jan", "Feb", "Mar", "Jan", "Feb", "Mar"), A1 = c(1L, 
2L, 3L, 1L, 2L, 3L), A2 = c(1L, 2L, 3L, 1L, 2L, 3L), A3 = c(1L, 
2L, 3L, 1L, 2L, 3L)), .Names = c("Year", "Month", "A1", "A2", 
"A3"), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5", "6"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...