根据R中的汇总行数据创建列

时间:2018-09-30 20:25:33

标签: r

我有一个包含历史价格回报的数据框。数据由日期列和许多资产列(表示为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包含Year 1月份所有回报的平均值。在此先感谢您的见解和/或解决方案。

3 个答案:

答案 0 :(得分:1)

看看基本功能的重塑。这基本上与帮助页面上的最后一个示例所解决的任务相同:

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变量充当扩展为“宽”的序列。

答案 1 :(得分:0)

使用 ser.write("run MODE-55\r\n") ,您可以完成

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部分确保我们仅聚合以字母“ A”开头的变量。

第二行创建变量names(df)[grep("^A", names(df)),其中包含值“ Average”。

Returns会将您的数据收集为长格式,而melt最终会散布到所需的输出中。

数据

dcast

答案 2 :(得分:0)

这是一个整洁的解决方案。我考虑了月份,以便可以订购它们,然后使用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