从R中的聚合行数据创建列
我有一个包含历史价格回报的数据框。数据由日期列和许多资产列(表示为A1、A2…)组织。每个资产列包含每个唯一历史日期的价格返回数据。我希望处理这些数据以创建一个包含许多资产列和一行数据的数据框架,其中数据行包含新列的行的聚合/平均值。新列需要的标题是原始资产名称,并与日期信息连接在一起。原始日期的简化示例如下:从R中的聚合行数据创建列,r,R,我有一个包含历史价格回报的数据框。数据由日期列和许多资产列(表示为A1、A2…)组织。每个资产列包含每个唯一历史日期的价格返回数据。我希望处理这些数据以创建一个包含许多资产列和一行数据的数据框架,其中数据行包含新列的行的聚合/平均值。新列需要的标题是原始资产名称,并与日期信息连接在一起。原始日期的简化示例如下: > df <- read.csv("data.csv", header=T) > df Year Month A1 A2 A3 1 2015 Jan 1 1
> 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
>测向
年份月份A1 A2 A3
2015年1月1日
2015年2月2日
2015年3月3日
4 2016年1月1日
5 2016年2月2日
2016年3月6日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
>df2 df2
返回A1.Jan A1.Feb A1.Mar A2.Jan A2.Feb A2.Mar A3.Jan A3.Feb A3.Mar
1平均值123123
为清楚起见,A1.Jan包含全年1月收益的平均值。提前感谢您提供的见解和/或解决方案。使用
数据。表
您可以
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
在第一行中,我们按月份
汇总数据。names(df)[grep(“^A”,names(df))
部分确保我们只聚合以字母“A”开头的变量
第二行创建变量返回包含值“Average”的
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"))
df查看基本函数重塑。这基本上与帮助页面上的最后一个示例所解决的任务相同:
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变量充当“广泛”分布的序列。这是一个tidyverse解决方案。我对月份进行了分解,以便对其进行排序,然后使用tidyr::gather()
将其转换为长格式,这样我就可以dplyr::group_by()
按月到dplyr::summary()
查找平均值:
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
库(dplyr)
图书馆(tidyr)
df%
tbl_df()
df$月百分比
系数(级别=格式(ISOdate(2000,1:12,1),%b”))
df_整洁%
聚集(资产、价值、-年、-月)%>%
集团单位(月、资产)%>%
总结(平均值=平均值))%>%
安排(资产,月)
迪菲
##tibble:9 x 3
##组:月[3]
#月平均资产
#
#1月1日A1 1
#2月2日A1 2
#3月3日A1 3
#2001年1月4日
#2月5日A2 2
#3月6日A2 3
#2001年1月7日
#2月8日A3 2
#3月9日A3 3
#转换为宽格式,如OP-不确定“简单”方式
#按asset.month排序列而不是使用“select()”的步骤
#(目前按字母顺序排序)。
df_整洁%>%
统一(回报率,c(资产,月),9月=“.”%>%
价差(收益率、平均值)
##A tible:1 x 9
#1.二月A1.一月A1.三月A2.二月A2.一月A2.三月A3.二月A3.一月A3.三月
#
# 1 2 1 3 2 1 3 2 1 3
这对分组效果很好。超高效且备受赞赏。这看起来是个不错的选择。我不打算使用表格,但可能会重新考虑。非常感谢。@FlyTrdr你是说“表格”吗与data.table
一样,除了data.frame
s(base R
-参见@42-)和tibble
s(tidyverse
-保罗的答案)之外,包是处理矩形数据的三种最常用方法之一这里有一个介绍:@保罗,也请考虑它是否解决了你的问题。谢谢。没有使用这个图书馆,但它看起来很有用。我会尝试一下。非常感谢没有问题,如果你认为这是你的问题的最佳解决方案,请回答我。