【问题标题】:Create missing observations in panel data在面板数据中创建缺失的观测值
【发布时间】:2014-08-17 17:14:59
【问题描述】:

我正在处理具有唯一案例标识符和观察时间点列(长格式)的面板数据。既有时间常数变量,也有随时间变化的观测值:

    id  time    tc1     obs1
1   101 1       male    4
2   101 2       male    5
3   101 3       male    3
4   102 1       female  6
5   102 3       female  2
6   103 1       male    2

对于我的模型,我现在需要每个时间点每个 id 具有完整记录的数据。换句话说,如果缺少观察结果,我仍然需要将观察变量的 id、时间、时间常数变量和 NA 放在一行中(如 (102, 2, "female", NA 行)在上面的例子中)。所以我的问题是:

  1. 如何确定我的数据集中是否已经存在具有唯一 id 和 time 组合的行?
  2. 如果没有,我该如何添加这一行、结转时间常数变量并用 NA 填充观察结果?

如果有人能对此有所了解,那就太好了。

提前非常感谢!


编辑

感谢大家的回复。这是我最终所做的,它混合了几种建议的方法。问题是我每行有几个随时间变化的变量(obs1-obsn),我没有让 dcast 适应它 - value.name 只需要参数。

# create all possible permutations of id and year
iddat = expand.grid(id = unique(dataset$id), time = (c(1996,1999,2002,2005,2008,2011)))
iddat <- iddat[order(iddat$id, iddat$time), ]

# add permutations to existing data, combinations so far missing are NA
dataset_new <- merge(dataset, iddat, all.x=TRUE, all.y=TRUE, by=c("id", "time"))

# drop time-constant variables from data
dataset_new[c("tc1", "tc2", "tc3")] <- list(NULL)

# merge back time-constant variables from original data
temp <- dataset[c("tc1", "tc2", "tc3")]
dataset_new <- merge(dataset_new, temp, by=c("id"))

# sort
dataset_new <- dataset_new[order(dataset_new$id, dataset_new$time), ]
dataset_new <- unique(dataset_new) # some rows are duplicates after last merge, no idea why

rm(temp)
rm(iddat)

一切顺利,再次感谢马特

【问题讨论】:

  • 您应该包含原始数据以使您的问题易于复制——看看dput
  • 但基本上,如果您有一个应该存在的id和时间列表,您可以使用merge将其与此数据合并。对于那些不存在的 id 和时间,您将获得 NA
  • 如果您需要创建一个包含所有可能的 id/time/tc1 组合的数据集以与merge 一起使用,您可以将expand.grid 与数据集中的适当信息一起使用:iddat = expand.grid(id = unique(dat$id), time = unique(dat$time), tc1 = unique(dat$tc1))
  • 有函数make.pbalancedmake.pconsecutive 在包plm (r-forge.r-project.org/R/?group_id= 406). 跨度>

标签: r panel


【解决方案1】:

可能有更优雅的方法,但这里有一种选择。我假设您需要idtime 的所有组合,但不需要tc1(即tc1 绑定到id)。

# your data
df <- read.table(text = "    id  time    tc1     obs1
1   101 1       male    4
2   101 2       male    5
3   101 3       male    3
4   102 1       female  6
5   102 3       female  2
6   103 1       male    2", header = TRUE)

首先将您的数据转换为宽格式以引入 NA,然后再转换回长格式。

library('reshape2')

df_wide <- dcast(
  df, 
  id + tc1 ~ time,
  value.var = "obs1", 
  fill = NA
)

df_long <- melt(
  df_wide, 
  id.vars = c("id","tc1"), 
  variable.name = "time",
  value.name = "obs1"
)

# sort by id and then time
df_long[order(df_long$id, df_long$time), ]
   id    tc1 time obs1
1 101   male    1    4
4 101   male    2    5
7 101   male    3    3
2 102 female    1    6
5 102 female    2   NA
8 102 female    3    2
3 103   male    1    2
6 103   male    2   NA
9 103   male    3   NA

【讨论】:

  • 您可以在重塑数据集时保留tc1,方法是在dcast 中使用id + tc1 ~ time,然后在id.vars = c("id","tc1") 中使用id.vars = c("id","tc1")variable.name = "time"melt 中。
  • @eipi10 啊哈,我们走了。感谢您的评论;我已经相应地编辑了我的答案。
【解决方案2】:

您可以创建一个空数据集,然后将匹配的记录合并。

 # Create dataset.  For you actual data ,you would replace c(1:3) with 
 # c(1:max(yourdata$id)) and adjust the number of time periods to match your data.
 id <- rep(c(1:3), each = 3)
 time <- rep(c(1:3), 3)
 df <- data.frame(id,time)


 test <- df[c(1,3,5,7,9),]
 test$tc1 <- c("male", "male", "female", "male", "male")
 test$obs1 <-c(4,5,3,6,2)

 merge(df, test, by.x = c("id","time"), by.y = c("id","time"), all.x = TRUE)

结果:

 id time    tc1 obs1
 1  1    1   male    4
 2  1    2   <NA>   NA
 3  1    3   male    5
 4  2    1   <NA>   NA
 5  2    2 female    3
 6  2    3   <NA>   NA
 7  3    1   male    6
 8  3    2   <NA>   NA
 9  3    3   male    2

【讨论】:

  • @kng229 答案的通用版本,可以处理因子 id 并自动设置时间范围:id_list &lt;- sort(rep(unique(df$id), max(df$time)-min(df$time) +1)) time_list &lt;- rep(min(df$time):max(df$time)) empty_panel &lt;- data.frame(id_list,time_list)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-15
  • 2016-07-04
  • 1970-01-01
相关资源
最近更新 更多