【问题标题】:Demeaning data on multiple levels in R [duplicate]R中多个级别的贬低数据[重复]
【发布时间】:2015-02-10 11:04:16
【问题描述】:

我有一个如下所示的数据框:

weekyear      Location_Id              priceA                   priceB
1    20101        6367                0.8712934                    8
2    20101        6380                0.1712934                    8
3    20102        6367                0.8712934                    4
4    20102        6380                0.4712934                    4
5    20103        6367                0.8712934                    1
6    20103        6380                0.8712934                    9

我想贬低 priceA 和 priceB。每个都按位置和时间索引。我想要

priceAnew = priceA_{location,time} - mean(over time)(priceA_{location}) - mean(over location)(priceA_{time})

这里的符号更清楚: https://stats.stackexchange.com/questions/126549/do-people-used-fixed-effects-in-lasso

有没有一种无痛的方法来做到这一点?

【问题讨论】:

    标签: r dataframe transform


    【解决方案1】:

    我猜你正在寻找类似的东西

    transform(dd, 
        newA = priceA-ave(priceA, weekyear)-ave(priceA, Location_Id),
        newB = priceB-ave(priceB, weekyear)-ave(priceB, Location_Id)
    )
    

    (其中dd 是您的data.frame 的名称)。这返回

      weekyear Location_Id    priceA priceB       newA      newB
    1    20101        6367 0.8712934      8 -0.5212934 -4.333333
    2    20101        6380 0.1712934      8 -0.8546267 -7.000000
    3    20102        6367 0.8712934      4 -0.6712934 -4.333333
    4    20102        6380 0.4712934      4 -0.7046267 -7.000000
    5    20103        6367 0.8712934      1 -0.8712934 -8.333333
    6    20103        6380 0.8712934      9 -0.5046267 -3.000000
    

    用于您的示例输入。如果您必须在很多很多列上执行此操作,我可能更喜欢循环。

    cols <- paste0("price", LETTERS[1:2])
    for(col in cols) {
        dd[[paste0("new", col)]] <- dd[[col]] - 
            ave(dd[[col]], dd$weekyear)-
            ave(dd[[col]], dd$Location_Id),
    }
    

    【讨论】:

    • 如果周围有 NA,则 ave 似乎失败了。我在文档中没有看到任何关于忽略 NA 的内容
    • 我试过 x = newA = priceA-ave(priceA, weekyear,FUN=mean,na.rm=TRUE)-ave(priceA, Location_IdFUN=mean,na.rm=TRUE) 但没有工作
    • 我会创建一个新的辅助函数:naave&lt;-function(...) ave(..., FUN=function(x) mean(x, na.rm=T))。然后只需使用naave 而不是ave(假设您想忽略这些值)。
    • 呃,我很抱歉回来了,但是如何在不手动输入的情况下对数据集中的所有列(或其中的 98/100)执行此操作?我尝试了自然替换,当我使用 ddnewcol = dd[column] + 等时,transform 似乎不喜欢它。(我打算遍历所有列)
    • 我添加了一个更新,它将遍历列名向量