假设我有两个数据框“值”和“权重”,我想按类别 (A, B, C) 计算加权中位数 coloumnwise (year1, year2) :

values <- data.frame(TICKER=c("A","A","B","B","B","C","C","C","C"), year1=c(1,2,3,4,5,6,7,8,9), year2=c(9,8,7,6,5,4,3,2,1))
weights <- data.frame(TICKER=c("A","A","B","B","B","C","C","C","C"), year1=c(0.3,0.7,0.25,0.25,0.5,0.1,0.1,0.6,0.2), year2=c(0.6,0.4,0.3,0.5,0.2,0.4,0.2,0.1,0.3))

为此,我想使用 ddply 和 weightedMedian 函数(包 matrixStats)。
output <- ddply(values, .(TICKER), colwise(weightedMedian(values, weights), na.rm=TRUE))

但是,我收到错误消息:
"(list) object cannot be coerced to type 'double'"

有人知道如何调整代码以获得有效的解决方案吗?

我试图将数据帧转换为矩阵(通过 as.matrix),因为 weightedMedian 需要一个矩阵作为输入。但是,这无济于事。
到目前为止我发现的唯一解决方案是使用子集的循环(但是,这非常慢而且不是很优雅)
output <- matrix(data=0, nrow=3, ncol=2)
for (i in 2:ncol(values)){
 for (j in 1:length(unique(values$TICKER))){
  values.j <- subset(values, values$TICKER == as.character(unique(values$TICKER)[j]))
  weights.j <-  subset(weights, weights$TICKER == as.character(unique(values$TICKER)[j]))
  output[j,(i-1)] <- weightedMedian(values.j[,i], weights.j[,i], na.rm=TRUE)
}}

任何帮助,将不胜感激。非常感谢。

最佳答案

除了 OP 提到的 weightedMedian 函数之外,Hmisc 包还提供了一个更通用的 wtd.quantile 函数。

我将两个 data.frames 拆分为列表,并将这些函数应用于嵌套 sapply 的两个年份变量。比较下面的结果,似乎 weightedMedian 产生了所需的结果。

要准备数据,请将值和权重沿其 TICKER 拆分为列表。

# split values and weights into lists by category
valuesList <- split(values, values$TICKER)
weightsList <- split(weights, values$TICKER)

如果我在上面的代码中使用 OP 问题中的 weightedMedian,我会得到以下信息:
library(matrixStats)
sapply(names(valuesList),
  function(i) sapply(names(valuesList[[i]])[-1],
                function(j) weightedMedian(valuesList[[i]][[j]],
                                           w=weightsList[[i]][[j]])))

        A        B C
year1 1.7 4.333333 8
year2 8.6 6.125000 3

另一个包 Hmisc 有一个加权分位数函数 wtd.quantile
# load Hmisc package
library(Hmisc)

sapply(names(valuesList),
   function(i) sapply(names(valuesList[[i]])[-1],
                   function(j) {
                     wtd.quantile(valuesList[[i]][[j]],
                                  weights=weightsList[[i]][[j]], probs=0.5)}))

这返回
myMedians
          A B C
year1.50% 2 5 9
year2.50% 9 7 4

从检查来看,matrixStats 的结果似乎更合理。例如,TICKER==C, year==2 不应该是 4。

关于r - 按类别计算加权中位数(matrixStats),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38014794/

10-12 17:15