太糟糕了,这是从stats.stackexchange.com迁移而来的,因为您可能会在那里得到更好的答案。
该mlogit
软件包需要有关个人的数据,并且可以接受“宽”或“长”数据。在前者中,每个人有一行表示选择的模式,对于特定于模式的变量(在您的示例中为时间和价格)的每个组合都有单独的列。在长格式中,每个人都有 n 行,其中 n 是模式的数量,第二列包含TRUE
或FALSE
指示为每个人选择的模式,以及每个模式特定变量的附加列。在内部,mlogit
使用长格式数据集,但您可以提供宽格式并mlogit
为您转换它。在这种情况下,只有两个变量,这可能是更好的选择。
由于mlogit
需要个人,并且您有个人数量,因此处理此问题的一种方法是扩展您的数据以使每种模式具有适当的行数,并使用变量组合填充生成的 data.frame。下面的代码就是这样做的:
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
with reflevel="car"
。这忽略了特定于模式的变量,只估计月份的影响(相对于模式 = 汽车)。
mlogit
这里有一个很好的教程。