【问题标题】:Winsorizing Panel Data (dataframe) by year and Trimming for certain conditions按年份对面板数据(数据框)进行 Winsorizing 并针对某些条件进行修剪
【发布时间】:2014-07-21 11:49:15
【问题描述】:

我正在尝试对面板数据和每年进行 Winsorize(将异常值替换为与平均值相差 2 或 3 个标准差的值)。我安装了包含这样一个功能的 robustHD 包,但是我无法在我的数据集上实现它。

我的数据集看起来类似于 Grunfeld(虽然我有 NA),但在同一年里有不同的公司。 (1935-1954)

> head(Grunfeld, 6)
  firm year   inv  value capital
1    1 1935 317.6 3078.5     2.8
2    1 1936 391.8 4661.7    52.6
3    1 1937 410.6 5387.1   156.9
4    1 1938 257.7 2792.2   209.2
5    1 1939 330.8 4313.2   203.4
6    1 1940 461.2 4643.9   207.2

我现在想做的是仅对所有公司的某些列(即 inv 和 value)进行 Winsorize,并将其存储在具有相同结构的数据框中。我尝试了以下代码:

目标基本上是获取原始数据帧的优化副本(所有结构都以相同的方式)。

如下所述,plyr 是拆分数据帧和应用函数的好方法,但我无法让它工作。

library(plm)
library(robustHD)
library(plyr)

data("Grunfeld", package="plm")

#Winsorize data  each year (over all firms) therefore split dataframe for each year and apply the winsorize function)

Grunfeld.w<-ddply(Grunfeld, .(year) function(x) winsorize(x$inv,x$value))

【问题讨论】:

    标签: r outliers panel-data


    【解决方案1】:

    您可以预先创建一个列表来存储数据帧。该列表的长度必须为 n,其中 n 是一年中唯一值的数量。

    library(plm)
    library(robustHD)
    data("Grunfeld", package="plm")
    
    ## determine unique values in year and their length
    unique_years <- unique(Grunfeld$year)
    n_unique_years <- length(unique_years)
    
    ## create an empty list of length 20
    Grunfeld.w <- vector("list", length=n_unique_years)
    
    for(i in 1:n_unique_years){
      Grunfeld.w[[i]]  <- winsorize(subset(Grunfeld, year==unique_years[i], 
                                           select=c(inv, value)))
    
      ## add the year field to each insorized data frame
      Grunfeld.w[[i]] <- cbind(Grunfeld.w[[i]], year=unique_years[i])
    }
    

    现在每个 Winsorized 数据都作为数据框存储在 Grunfeld.w 列表中。如果您只想要一个数据框,请使用以下内容:

    ## convert the list to one data frame
    temp <- data.frame(do.call("rbind", Grunfeld.w))
    

    至于您的第二个问题,我猜您想根据某些特征(例如,x 中 >5000)选择“主题”,但您不想使用 subset 函数。那你就可以用dplyrfilter函数了。我再用Grunfeld的数据来说明:

    library(dplyr)
    Grunfeld_gt1940 <- filter(Grunfeld, year>1940) ## the "gt" stands for "greater than". 
    

    已编辑

    如果你想让新的数据和原来的数据一样排列,可以使用rownames提取原来的顺序:

    temp <- temp[order(as.numeric(rownames(temp))), ]
    
    ## Add the winsorized variables to the original data
    names(temp)[1:2] <- c("inv_wins", "value_wins")
    Grunfeld_new <- data.frame(Grunfeld, temp[, c("inv_wins", "value_wins")])
    

    【讨论】:

    • 谢谢你的回答!不知何故,转换为 data.frame 不起作用。另外,如何以与原始数据相同的方式重新排列 Winsorized 数据?
    • 其实do.call("rbind", Grunfeld.w)将列表转换为矩阵,而不是data.frame。所以我已经纠正了这个错误。
    • 我尝试实现您的代码,但不幸的是它与我的 NA 不兼容,我收到以下错误:特征错误(R,对称 = TRUE):'x' 中的无限或缺失值> traceback() 6: stop("'x'中的无限或缺失值") 5: eigen(R, symmetric = TRUE) 4: winsorize.matrix(as.matrix(x, ...)) 3: winsorize(as .matrix(x, ...)) 2: winsorize.data.frame(subset(mydata, time == unique_years[i],
    • 您可以删除缺失值并应用winsorize。然后在for 循环中的winsorize 中包含na.omit。我认为这比填补缺失数据然后对它们进行 Winsorize 更简洁,这让我很难理解。
    • 你会在哪里包含na.omit,在此之前如何删除缺失值?干杯
    猜你喜欢
    • 2021-08-08
    • 2019-04-09
    • 2018-11-09
    • 2020-04-13
    • 2019-04-17
    • 2019-02-22
    • 1970-01-01
    • 2021-08-29
    • 1970-01-01
    相关资源
    最近更新 更多