【问题标题】:scale columns of an xts object缩放 xts 对象的列
【发布时间】:2013-05-30 01:08:18
【问题描述】:

我经常处理xts 格式的数据,并且经常必须对它们进行缩放(比如在某个日期等于 100)。我目前使用一个函数来执行此操作,该函数使用for-loop 工作——但这​​似乎不是很功能

我现在是这样做的:

df1 <- data.frame(rnorm(100), runif(100), 1:100*rnorm(100))
dfx <- xts(df1, order.by = seq(as.Date("2001-01-01"), by='mon', length.out=100))

dfxColScl <- function(dfrm, pos=1, idx = 100)
{
    scaledDF <- dfrm
    for (i in 1:ncol(dfrm)) {
        scaledDF[, i] <- dfrm[,i] / as.numeric(dfrm[pos, i]) * idx
    }
    return(scaledDF)
}

是否有一些聪明的apply 类型函数是R 的方法?

【问题讨论】:

    标签: r for-loop xts apply


    【解决方案1】:

    sweep 可用于将矩阵除以一行。

    dfx.scaled2 <- sweep(100*dfx, 2, dfx[1], "/")
    all.equal(dfx.scaled, dfx.scaled2) # same result as @Joshua
    #[1] TRUE
    

    【讨论】:

    • 不错。我认为如果不使用 coredata(dfx[1])sweep 将无法工作,但对 array 的内部调用会为您解决这个问题。
    【解决方案2】:

    您可以使用apply.daily。请注意,您仍然必须在要除以的行上使用 coredata,因为 xts/zoo 操作在执行操作之前总是按索引对齐。

    dfx.scaled <- apply.daily(dfx, function(x) x/coredata(dfx[1,])*100)
    

    【讨论】:

    • +1,谢谢。所以如果这是月度数据,我会使用 apply.monthly?
    • @ricardo:在您的示例中,dfx 每月,apply.daily 工作。它之所以有效,是因为dfx 的索引是日期。
    • 请原谅——在我问之前我没有尝试过。我由此推断apply.daily 在所有情况下都可以工作吗?
    • @ricardo:它适用于对象索引为Date 对象的所有情况。当索引为yearmonyearqtr 时它可能会起作用,但我不确定。如果索引每天有多个观察值,它肯定不会起作用,因为apply.daily 会将它们聚合成每天一个观察值。
    猜你喜欢
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 2020-07-19
    • 2020-11-15
    • 2011-11-25
    • 2019-06-15
    相关资源
    最近更新 更多