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