R pmg 中的 Fama Macbeth 回归
Fama Macbeth Regression in R pmg
在过去的几天里,我一直在尝试寻找如何在 R 中进行 Fama Macbeth 回归。建议将 plm
包与 pmg
一起使用,但是我所做的每一次尝试 returns我的时间段数量不足。
我的数据集包含 2828419 个观察值和 13 列变量,我希望对其进行多重横截面回归。
我的公司由 seriesis 指定,我有一个可变日期并想做以下 Fama Macbeth 回归:
totret ~ size
totret ~ momentum
totret ~ reversal
totret ~ volatility
totret ~ value size
totret ~ value + size + momentum
totret ~ value + size + momentum + reversal + volatility
我一直在使用这个命令:
fpmg <- pmg(totret ~ momentum, Data, index = c("date", "seriesid")
哪个returns:Error in pmg(totret ~ mom, Dataset, index = c("seriesid", "datem")) : Insufficient number of time periods
我用我的数据集作为数据表、数据框和 pdataframe 进行了尝试。切换索引也不行。
我的数据也包含 NA。
谁可以解决这个问题,或者为我找到一个不同的方式来做 Fama Macbeth?
这几乎可以肯定是由于公式中的变量中包含 NA。错误消息不是很有帮助 - 它可能不是 "too few time periods to estimate" 的情况,很可能是 "there are firm/unit IDs that are not represented across all time periods" 的情况,因为丢失的数据被丢弃。
您有两个选择 - 估算缺失数据或删除含有缺失数据的观测值(后者是一种快速测试,可以在决定您想要执行的操作是否对估计有效之前验证模型是否正常工作)。
如果您的数据中的缺失确实是随机的,那么您可能只需要删除带有缺失的观测值就可以了。否则你应该估算。这里的一个常见策略是估算多次(至少 5 次),然后对这 5 个结果数据集中的每一个进行估算,并将效果平均在一起。 Amelia
或 mice
是非常强大的插补包。我喜欢 Amelia
因为一次调用就可以为那么多结果数据集估算 n
次,并且很容易传入一组变量而不用估算(例如,id 变量或时间段) idvars
参数。
编辑:我深入研究了源代码以查看触发错误的位置,这就是问题所在 - 再次可能是由丢失数据引起的,但它确实与您的自由度相互作用:
...
# part of the code where error is triggered below, here is context:
# X = matrix of the RHS of your model including intercept, so X[,1] is all 1s
# k = number of coefficients used determined by length(coef(plm.model))
# ind = vector of ID values
# so t here is the minimum value from a count of occurrences for each unique ID
t <- min(tapply(X[,1], ind, length))
# then if the minimum number of times a single ID appears across time is
# less than the number of coefficients + 1, you do not have enough time
# points (for that ID/those IDs) to estimate.
if (t < (k + 1))
stop("Insufficient number of time periods")
这就是触发您的错误的原因。因此,插补绝对是一种解决方案,但您的数据中可能只有一个违规者,重要的是,一旦满足此条件,您的模型将 运行 正常 且 缺少数据。
最近,我修复了 R 中的 Fama Macbeth 回归。
从具有行内所有特征的数据 Table 中,以下工作有效并提供了对回归进行平均加权或应用权重的机会(删除“,weights = marketcap”以表示平均加权)。 totret是总return变量,logmarket是市值的对数。
logmarket<- df %>%
group_by(date) %>%
summarise(constant = summary(lm(totret~logmarket, weights = marketcap))$coefficient[1], rsquared = summary(lm(totret~logmarket*, weights = marketcap*))$r.squared, beta= summary(lm(totret~logmarket, weights = marketcap))$coefficient[2])
你获得了一个具有每月 alpha(常量)、beta(beta)、R 平方(rsquared)的 DataFrame。
要在数据框中使用 t 统计量检索系数:
Summarystatistics <- as.data.frame(matrix(data=NA, nrow=6, ncol=1)
names(Summarystatistics) <- "logmarket"
row.names(Summarystatistics) <- c("constant","t-stat", "beta", "tstat", "R^2", "observations")
Summarystatistics[1,1] <- mean(logmarket$constant)
Summarystatistics[2,1] <- coeftest(lm(logmarket$constant~1))[1,3]
Summarystatistics[3,1] <- mean(logmarket$beta)
Summarystatistics[4,1] <- coeftest(lm(logmarket$beta~1))[1,3]
Summarystatistics[5,1] <- mean(logmarket$rsquared)
Summarystatistics[6,1] <- nrow(subset(df, !is.na(logmarket)))
有一些“seriesid”条目只有一个条目。因此 pmg 给出了错误。如果你做这样的事情(使用你使用的变量名),它会停止错误:
try2 <- try2 %>%
group_by(cusip) %>%
mutate(flag = (if (length(cusip)==1) {1} else {0})) %>%
ungroup() %>%
filter(flag == 0)
在过去的几天里,我一直在尝试寻找如何在 R 中进行 Fama Macbeth 回归。建议将 plm
包与 pmg
一起使用,但是我所做的每一次尝试 returns我的时间段数量不足。
我的数据集包含 2828419 个观察值和 13 列变量,我希望对其进行多重横截面回归。 我的公司由 seriesis 指定,我有一个可变日期并想做以下 Fama Macbeth 回归:
totret ~ size
totret ~ momentum
totret ~ reversal
totret ~ volatility
totret ~ value size
totret ~ value + size + momentum
totret ~ value + size + momentum + reversal + volatility
我一直在使用这个命令:
fpmg <- pmg(totret ~ momentum, Data, index = c("date", "seriesid")
哪个returns:Error in pmg(totret ~ mom, Dataset, index = c("seriesid", "datem")) : Insufficient number of time periods
我用我的数据集作为数据表、数据框和 pdataframe 进行了尝试。切换索引也不行。
我的数据也包含 NA。
谁可以解决这个问题,或者为我找到一个不同的方式来做 Fama Macbeth?
这几乎可以肯定是由于公式中的变量中包含 NA。错误消息不是很有帮助 - 它可能不是 "too few time periods to estimate" 的情况,很可能是 "there are firm/unit IDs that are not represented across all time periods" 的情况,因为丢失的数据被丢弃。
您有两个选择 - 估算缺失数据或删除含有缺失数据的观测值(后者是一种快速测试,可以在决定您想要执行的操作是否对估计有效之前验证模型是否正常工作)。
如果您的数据中的缺失确实是随机的,那么您可能只需要删除带有缺失的观测值就可以了。否则你应该估算。这里的一个常见策略是估算多次(至少 5 次),然后对这 5 个结果数据集中的每一个进行估算,并将效果平均在一起。 Amelia
或 mice
是非常强大的插补包。我喜欢 Amelia
因为一次调用就可以为那么多结果数据集估算 n
次,并且很容易传入一组变量而不用估算(例如,id 变量或时间段) idvars
参数。
编辑:我深入研究了源代码以查看触发错误的位置,这就是问题所在 - 再次可能是由丢失数据引起的,但它确实与您的自由度相互作用:
...
# part of the code where error is triggered below, here is context:
# X = matrix of the RHS of your model including intercept, so X[,1] is all 1s
# k = number of coefficients used determined by length(coef(plm.model))
# ind = vector of ID values
# so t here is the minimum value from a count of occurrences for each unique ID
t <- min(tapply(X[,1], ind, length))
# then if the minimum number of times a single ID appears across time is
# less than the number of coefficients + 1, you do not have enough time
# points (for that ID/those IDs) to estimate.
if (t < (k + 1))
stop("Insufficient number of time periods")
这就是触发您的错误的原因。因此,插补绝对是一种解决方案,但您的数据中可能只有一个违规者,重要的是,一旦满足此条件,您的模型将 运行 正常 且 缺少数据。
最近,我修复了 R 中的 Fama Macbeth 回归。 从具有行内所有特征的数据 Table 中,以下工作有效并提供了对回归进行平均加权或应用权重的机会(删除“,weights = marketcap”以表示平均加权)。 totret是总return变量,logmarket是市值的对数。
logmarket<- df %>%
group_by(date) %>%
summarise(constant = summary(lm(totret~logmarket, weights = marketcap))$coefficient[1], rsquared = summary(lm(totret~logmarket*, weights = marketcap*))$r.squared, beta= summary(lm(totret~logmarket, weights = marketcap))$coefficient[2])
你获得了一个具有每月 alpha(常量)、beta(beta)、R 平方(rsquared)的 DataFrame。
要在数据框中使用 t 统计量检索系数:
Summarystatistics <- as.data.frame(matrix(data=NA, nrow=6, ncol=1)
names(Summarystatistics) <- "logmarket"
row.names(Summarystatistics) <- c("constant","t-stat", "beta", "tstat", "R^2", "observations")
Summarystatistics[1,1] <- mean(logmarket$constant)
Summarystatistics[2,1] <- coeftest(lm(logmarket$constant~1))[1,3]
Summarystatistics[3,1] <- mean(logmarket$beta)
Summarystatistics[4,1] <- coeftest(lm(logmarket$beta~1))[1,3]
Summarystatistics[5,1] <- mean(logmarket$rsquared)
Summarystatistics[6,1] <- nrow(subset(df, !is.na(logmarket)))
有一些“seriesid”条目只有一个条目。因此 pmg 给出了错误。如果你做这样的事情(使用你使用的变量名),它会停止错误:
try2 <- try2 %>%
group_by(cusip) %>%
mutate(flag = (if (length(cusip)==1) {1} else {0})) %>%
ungroup() %>%
filter(flag == 0)