我想估计R中多项Logit模型的参数,并想知道如何正确构建我的数据。我正在使用“mlogit”包。
目的是模拟人们对交通方式的选择。但是,数据集是聚合级别的时间序列,例如:
必须将此数据从分组计数数据重新整形为未分组数据。我的方法是为每个人创建三个新行,所以我最终得到一个如下所示的数据集:
对于每个人在分组数据中的选择,我创建了三个新行并使用chid来绑定这三个 一起排。我现在想跑: mlogit.data(MyData,choice =“choice”,chid.var =“chid”,alt.var =“mode”)。
这是正确的做法吗?或者我误解了chid功能的目的?
答案 0 :(得分:3)
这是从stats.stackexchange.com迁移出来的太糟糕了,因为你可能会在那里找到更好的答案。
mlogit
包期望个人数据,并且可以接受“宽”或“长”数据。在前者中,每个人有一行表示所选模式,每个组合的单独列用于特定于模式的变量(示例中的时间和价格)。在长格式中,每个人都有n行,其中n是模式的数量,第二列包含TRUE
或FALSE
,表示为每个人选择了哪种模式,还有一列用于每个特定于模式的变量。在内部,mlogit
使用长格式数据集,但您可以提供宽格式并为您进行mlogit
转换。在这种情况下,只有两个变量,这可能是更好的选择。
由于mlogit
期望个人,并且您拥有个人数量,因此解决此问题的一种方法是将数据扩展为每种模式具有适当的行数,并填写结果数据。变量组合。下面的代码就是这样:
df.agg <- data.frame(month=1:4,car=c(3465,3674,3543,4334),bus=c(1543,2561,2432,1266),bicycle=c(453,234,123,524))
df.lvl <- data.frame(mode=c("car","bus","bicycle"), price=c(120,60,0), time=c(5,10,30))
get.mnth <- function(mnth) data.frame(mode=rep(names(df.agg[2:4]),df.agg[mnth,2:4]),month=mnth)
df <- do.call(rbind,lapply(df.agg$month,get.mnth))
cols <- unlist(lapply(df.lvl$mode,function(x)paste(names(df.lvl)[2:3],x,sep=".")))
cols <- with(df.lvl,setNames(as.vector(apply(df.lvl[2:3],1,c)),cols))
df <- data.frame(df, as.list(cols))
head(df)
# mode month price.car time.car price.bus time.bus price.bicycle time.bicycle
# 1 car 1 120 5 60 10 0 30
# 2 car 1 120 5 60 10 0 30
# 3 car 1 120 5 60 10 0 30
# 4 car 1 120 5 60 10 0 30
# 5 car 1 120 5 60 10 0 30
# 6 car 1 120 5 60 10 0 30
现在我们可以使用mlogit(...)
library(mlogit)
fit <- mlogit(mode ~ price+time|0 , df, shape = "wide", varying = 3:8)
summary(fit)
#...
# Frequencies of alternatives:
# bicycle bus car
# 0.055234 0.323037 0.621729
#
# Coefficients :
# Estimate Std. Error t-value Pr(>|t|)
# price 0.0047375 0.0003936 12.036 < 2.2e-16 ***
# time -0.0740975 0.0024303 -30.489 < 2.2e-16 ***
# ...
coef(fit)["time"]/coef(fit)["price"]
# time
# -15.64069
所以这表明减少旅行时间1(分钟?)值约15(美元)?
此分析忽略month
变量。我不清楚如何将其纳入,因为月份既不是特定模式,也不是个人特定的。您可以“假装”该月份是针对具体个人的,并使用类似于mode ~ price+time|month
的模型公式,但对于您的数据集,系统在计算上是单数的。
要从其他答案中重现结果,您可以将mode ~ 1|month
与reflevel="car"
一起使用。这会忽略特定于模式的变量,只估计月份的影响(相对于模式=汽车)。
mlogit
here上有一个很好的教程。
答案 1 :(得分:0)
您尝试成为模型一部分的价格和时间是真正的变量吗?
如果没有,那么你就不需要&#34; unaggregate&#34;那个数据。直接计算结果(即使使用协变量)也是完美的。我不知道在mlogit中这样做的细节,但是使用multinom,它很简单,我想用mlogit可以做到这一点:
# Assuming your original data frame is saved in "df" below
library(nnet)
response <- as.matrix(df[,c('Car', 'Bus', 'Bicycle')])
predictor <- df$Month
# Determine how the multinomial distribution parameter estimates
# are changing as a function of time
fit <- multinom(response ~ predictor)
在上述情况下,结果的计数直接用于一个协变量,&#34;月&#34;。如果您不关心协变量,您也可以使用multinom(response ~ 1)
,但很难说出您真正想要做的事情。
浏览&#34; TravelMode&#34;尽管如此,我确信你选择的选项是正确的,如果你真的想要按照每个人的个人记录去做。