检查面板观察的因子值变化

Checking the change in factor value for panel observations

我有一个面板数据集,如下所示:

library(plm)
library(Hmisc)
library(data.table)
set.seed(1)
DT <- data.table(panelID = sample(50,50),                                                    # Creates a panel ID
                      Country = c(rep("Albania",30),rep("Belarus",50), rep("Chilipepper",20)),       
                      some_NA = sample(0:5, 6),                                             
                      some_NA_factor = sample(0:5, 6),         
                      Group = c(rep(1,20),rep(2,20),rep(3,20),rep(4,20),rep(5,20)),
                      Time = rep(seq(as.Date("2010-01-03"), length=20, by="1 month") - 1,5),
                      norm = round(runif(100)/10,2),
                      Income = round(rnorm(10,-5,5),2),
                      Happiness = sample(10,10),
                      Sex = round(rnorm(10,0.75,0.3),2),
                      Age = sample(100,100),
                      Educ = round(rnorm(10,0.75,0.3),2))           
DT [, uniqueID := .I]                                                                        # Creates a unique ID     
DT[DT == 0] <- NA                                                                            # 
DT$some_NA_factor <- factor(DT$some_NA_factor)
DTp <- plm::pdata.frame(DT, index= c("panelID", "Time"))

我想针对每个小组观察评估 some_NA_factor 或例如 Country 从一个时间段到另一个时间段的变化(1 表示变化,0 没有变化)。我想写这样的东西:

setDT(DT)[, difference := c(-1,1)*diff(some_NA_factor), by=panelID]

但是涉及到factors我不知道怎么写。如果我将此应用于 data.table 我预计会得到:

Warning messages:
1: In Ops.factor(c(-1, 1), diff(weight)) : ‘*’ not meaningful for factors

如果我将同样的事情应用到 pdata.frame。我得到:

setDT(DTp)[, difference := c(-1,1)*diff(some_NA_factor), by=panelID]
Error in alloc.col(x) : 
  Internal error: length of names (14) is not length of dt (13)

此外,将此应用于我的实际数据时,出现以下错误:

Supplied 107438 items to be assigned to group 1 of size 2 in column 'difference'. The RHS length must either be 1 (single values are ok) or match the LHS length exactly. If you wish to 'recycle' the RHS please use rep() explicitly to make this intent clear to readers of your code.

我不确定为什么会这样(我似乎无法在示例中重现它)。

有什么想法吗?

让我们一步一步来。

我想评估,对于每个面板观察,some_NA_factor 或例如 Country 是否从一个时间段变化到另一个时间段(1 表示变化,0 表示没有变化)。

您提供了以下代码:

# actual code:
setDT(DT)[, difference := c(-1,1)*diff(some_NA_factor), by=panelID]

我可以看到那里有一些问题。首先,您不需要 setDT(DT):您将 DT 定义为 data.table,因此不需要再次将其转换为现有的内容。其次,如果你想要零表示没有变化,1 表示变化,你希望乘以 c(-1, 1) 得到什么?最后,也是最重要的一点,乘法对于因子没有意义,所以我们需要将 diff 转换为数字:

# proposed code:
DT[, difference := 1*(diff(as.numeric(some_NA_factor)) != 0), by=panelID]

这里我们计算数值向量的差值,它是数值型的,并评估它是否不为零(即 return TRUE)。我们将其转换为数字乘以 1(TRUE 等于 1)。

区分 DTp

中的因子

我没有安装 {plm},但在阅读文档时我觉得 plm::pdata.frame 函数 return 是 class pdata.frame。我不确定 setDT 是否能够毫无问题地转换特定的 class,所以如果我是你,我会先将那个 pdata.frame 对象转换为 data.frame(它使用自己的 S3 方法),然后 then 到 data.table:

library(plm)
DTp <- setDT(as.data.frame(pdata.frame(DT, index= c("panelID", "Time"))))

计算 some_NA_factor 的差异将与上面显示的类似。