将数据从宽格式转换为长格式,保留 dv 的所有替代项并添加一个选择变量

Convert data from wide to long format keeping all alternatives of the dv and adding a choice variable

我尝试让我的数据与 -package in 一起使用。我用mlogit.data命令把宽数据格式转换成长格式失败了,所以我用melt自己试了一下。

这是我目前所拥有的(case 是一个案例标识符,dv 将是因变量,table 是宽格式的数据,newdata 长格式):

case<-c(1,2,3)
dv<-c(1,2,3)
table<-as.data.frame(cbind(IssueID, dv))

newdata<-melt(setDT(table), id.vars = c("IssueID"), measure.vars = c("dv"))

宽幅面:

   case dv
1:    1  1
2:    2  2
3:    3  3

长格式:

   IssueID variable value
1:       1       dv     1
2:       2       dv     2
3:       3       dv     3

但是,对于 运行 具有 mlogit 的数据,我需要一个数据集,其中包含每个案例的因变量的所有值,以及一个用于存储选择了这些备选方案的信息的虚拟对象按观察单位。

可用数据应如下所示:

#case2<-c(1,1,1,2,2,2,3,3,3)
#variable2<-(c("dv","dv","dv","dv","dv","dv","dv","dv","dv"))
#value2<-c(1,2,3,1,2,3,1,2,3)
#choice2<-c(1,0,0,0,1,0,0,0,1)
#newdata2<-as.data.frame(cbind(case2, variable2,value2,choice2))

  case2 variable2 value2 choice2
1     1        dv      1       1
2     1        dv      2       0
3     1        dv      3       0
4     2        dv      1       0
5     2        dv      2       1
6     2        dv      3       0
7     3        dv      1       0
8     3        dv      2       0
9     3        dv      3       1

您对执行此操作的代码有什么建议吗?这样我就不必手动编写 choice 变量的代码了?感谢您的协助。

或许,您可以使用 completefill 从数据的长格式中实现这一点。

library(dplyr)
library(tidyr)

df %>%
  mutate(choice = 1) %>%
  complete(IssueID, value = seq(min(value), max(value)), 
           fill = list(choice = 0)) %>%
  fill(variable)


#  IssueID value variable choice
#    <int> <int> <fct>     <dbl>
#1       1     1 dv            1
#2       1     2 dv            0
#3       1     3 dv            0
#4       2     1 dv            0
#5       2     2 dv            1
#6       2     3 dv            0
#7       3     1 dv            0
#8       3     2 dv            0
#9       3     3 dv            1

数据

df <- structure(list(IssueID = 1:3, variable = structure(c(1L, 1L, 
1L), .Label = "dv", class = "factor"), value = 1:3),
class = "data.frame", row.names = c(NA, -3L))

您可以使用 expand.grid 创建包含 case 和 dv 的所有排列的数据框。然后 matchpasted 列上。

res <- transform(cbind(with(dat, expand.grid(case=case, dv=dv)), var="dv"), choice=0)
res$choice[match(Reduce(paste, dat), Reduce(paste, res[1:2]))] <- 1
res
#   case dv var choice
# 1    1  1  dv      1
# 2    2  1  dv      0
# 3    3  1  dv      0
# 4    1  2  dv      0
# 5    2  2  dv      1
# 6    3  2  dv      0
# 7    1  3  dv      0
# 8    2  3  dv      0
# 9    3  3  dv      1

数据

dat <- data.frame(case=1:3, dv=1:3)

您可以按如下方式使用包 data.table

library(data.table)
setDT(df, key = c("IssueID", "value"))

df2 <- df[CJ(1:3, 1:3), .(IssueID, variable = "dv", value, choice = +!is.na(variable))]

df2
#        IssueID variable value choice
#     1:       1       dv     1      1
#     2:       1       dv     2      0
#     3:       1       dv     3      0
#     4:       2       dv     1      0
#     5:       2       dv     2      1
#     6:       2       dv     3      0
#     7:       3       dv     1      0
#     8:       3       dv     2      0
#     9:       3       dv     3      1

数据

df <- structure(list(IssueID = 1:3, variable = structure(c(1L, 1L, 
1L), .Label = "dv", class = "factor"), value = 1:3),
class = "data.frame", row.names = c(NA, -3L))