【问题标题】:sort data into deciles based on a rolling subset基于滚动子集将数据分类为十分位数
【发布时间】:2016-05-25 09:31:53
【问题描述】:

我正在尝试使用 R 复制 Fama French 1993 论文。我需要进行以下排序:

  1. 每个月,
  2. 仅计算 NYSE 股票的 ME 十分位断点
  3. 将所有股票按 2 中创建的十分位数排序。

数据生成:

    set.seed(1234)
    n = 120
    stocks <- c("A", "B", "C", "D", "E")
    exchange <- c("NYSE", "NASDAQ", "AMEX")
    df <- as.data.frame(cbind(Month = 1:12,
                      exchangeCode = exchange[round(runif(n, 1, 3))],
                      Stock = stocks[round(runif(n, 1, 5))],
                      ME=floor(100*abs(rnorm(n)))))

期望的输出:

ME_NYSE_vals <- as.numeric(paste(df[df$Month==1 & df$exchangeCode=="NYSE","ME"]))

ME_ALL_vals <- as.numeric(paste(df[df$Month==1,"ME"]))

cut(x = ME_ALL_vals,
breaks = c(-Inf,quantile(ME_NYSE_vals,probs=seq(.1,.9,.1)),+Inf),
labels = 1:10
)

应根据 ME_NSYE_vals 计算休息时间。削减应适用于每个月的所有 ME_ALL_vals。

【问题讨论】:

  • 添加set.seed,减少数据集并添加您想要的输出。
  • 如果你只希望 NYSE 在结果数据中,你可以在 group_by 之前过滤:df %&gt;% filter(exchangeCode == "NYSE") %&gt;% group_by(Month) %&gt;% mutate(nTile = ntile(ME, 10))
  • 感谢您的评论。我已更新问题以更好地反映正在寻求的内容。

标签: r sorting data.table dplyr percentile


【解决方案1】:

如果打算保留整个数据框,但只为 NYSE 值生成十分位数,则下面的代码可以执行此操作。关键是只为与 NYSE 值相关的条目生成十分位数,但要保持完整的数据集实现某种形式的部分排序。

# Libs
Vectorize(require)(package = c("dplyr", "magrittr"),
                   character.only = TRUE)
# Transformations
df %<>%
    mutate(nTileNYSE = ifelse(exchangeCode == "NYSE", ntile(ME, 10), NA))
    arrange(nTileNYSE)

代码已应用于数据:

set.seed(1)
df <- as.data.frame(cbind(exchangeCode = c("NYSE", "NASDAQ"), 
                          Stock = c("A", "B", "C", "A"), 
                          Month = 1:12,
                          ME=rnorm(1200)))

第二种方法

根据 cmets 中的讨论,我建议采用以下方法:

# Libs --------------------------------------------------------------------

Vectorize(require)(package = c( "tidyr", "dplyr", "magrittr", "xts", "Hmisc"),
                   char = TRUE)

# Data generation ---------------------------------------------------------

set.seed(1234)
n = 120
stocks <- c("A", "B", "C", "D", "E")
exchange <- c("NYSE", "NASDAQ", "AMEX")
df <- as.data.frame(cbind(Month = 1:12,
                          exchangeCode = exchange[round(runif(n, 1, 3))],
                          Stock = stocks[round(runif(n, 1, 5))],
                          ME = floor(100*abs(rnorm(n)))))

# Transformations ---------------------------------------------------------

# For some reason this was needed
df$ME <- as.numeric(as.character(df$ME))

# Generate cuts
dfNtiles <- df %>% 
  arrange(exchangeCode, Month, ME) %>% 
  group_by(exchangeCode, Month) %>% 
  mutate(cutsBsdOnNYSE = cut(x = ME, 
                             breaks = cut2(x = df$ME[df$exchangeCode == "NYSE"],
                                           g = 10, onlycuts = TRUE))) %>% 
  ungroup() %>% 
  group_by(cutsBsdOnNYSE) %>% 
  mutate(grpBsdOnNYSE = n())

很简单

  • 生成反映数据子集的切割括号。

  • 将这些括号应用于整个向量(ME)

  • 对获得的组进行编号以便创建组标识符

    归结为:

【讨论】:

  • 感谢您的评论。我已更新问题以更好地反映正在寻求的内容。
  • 您可以使用来自Hmisc 包的cut 导出切割值:cut2(x = as.numeric(as.character(df$ME[df$exchangeCode == "NYSE"])), g = 10, onlycuts = TRUE)
  • 谢谢!我有削减,但我如何计算它们并将它们应用于每个月的所有 ME。我的“削减”会在给定的一个月内做到这一点,但我无法弄清楚如何每个月“滚动”它们......我还不想诉诸循环。一定有更好的办法……
  • 对不起,必须更新....谢谢!但是,削减不会按月滚动。 cutBsdOnNYSE 使用所有 df$ME[df$exchangeCode == "NYSE"] 计算,但这应该按月计算,即每个月都需要重新计算削减。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 2021-12-21
  • 2018-11-05
  • 2022-08-24
  • 1970-01-01
相关资源
最近更新 更多