R:如何为多项式 logit 格式化我的数据?
R: how to format my data for multinomial logit?
我正在 R 上复制一些 Stata 代码,我想使用同名包中的 mlogit
函数执行多项逻辑回归(我知道有一个 multinom
在 nnet
中的功能,但我不想使用这个)。
我的问题是,要使用 mlogit
,我需要使用 mlogit.data
格式化我的数据,但我不知道如何正确格式化它。将我的数据与文档和 this question 中的示例中使用的数据进行比较,我意识到它们的形式不同。
的确,我使用的数据是这样的:
df <- data.frame(ID = seq(1, 10),
type = c(2, 3, 4, 2, 1, 1, 4, 1, 3, 2),
age = c(28, 31, 12, 1, 49, 80, 36, 53, 22, 10),
dum1 = c(1, 0, 0, 0, 0, 1, 0, 1, 1, 0),
dum2 = c(1, 0, 1, 1, 0, 0, 1, 0, 1, 0))
ID type age dum1 dum2
1 1 2 28 1 1
2 2 3 31 0 0
3 3 4 12 0 1
4 4 2 1 0 1
5 5 1 49 0 0
6 6 1 80 1 0
7 7 4 36 0 1
8 8 1 53 1 0
9 9 3 22 1 1
10 10 2 10 0 0
而他们使用的数据如下:
key altkey A B C D
1 201005131 1 2.6 118.17 117 0
2 201005131 2 1.4 117.11 115 0
3 201005131 3 1.1 117.38 122 1
4 201005131 4 24.6 NA 122 0
5 201005131 5 48.6 91.90 122 0
6 201005131 6 59.8 NA 122 0
7 201005132 1 20.2 118.23 113 0
8 201005132 2 2.5 123.67 120 1
9 201005132 3 7.4 116.30 120 0
10 201005132 4 2.8 118.86 120 0
11 201005132 5 6.9 124.72 120 0
12 201005132 6 2.5 123.81 120 0
如您所见,在他们的案例中,有一列 altkey
详细说明每个 key
的每个类别,还有一列 D
显示选择了哪个选项由人。
但是,我只有一列 (type
) 显示了个人的选择,但没有显示其他备选方案或每个备选方案的其他变量的值。当我尝试申请 mlogit
时,我有:
library(mlogit)
mlogit(type ~ age + dum1 + dum2, df)
Error in data.frame(lapply(index, function(x) x[drop = TRUE]), row.names = rownames(mydata)) :
row names supplied are of the wrong length
因此,如何格式化我的数据,使其符合 mlogit
要求的数据类型?
编辑: 按照@edsandorf 的建议,我修改了我的数据框并且 mlogit.data
有效,但现在所有其他解释变量对于每个替代项都具有相同的值。我应该在所选替代项为 0 或 FALSE 的行中将这些变量设置为 0 吗? (事实上 ,有人可以告诉我从我所在的位置到 mlogit
结果的过程,因为我没有得到我估计错误的地方吗?)
我在这里显示的数据(df
)不是我的真实数据。然而,它是完全相同的形式:一列有备选方案的选择(type
),一列有假人和年龄等。
这是我到目前为止所做的程序(我没有将替代项设置为 0):
# create a dataframe with all alternatives for each ID
qqch <- data.frame(ID = rep(df$ID, each = 4),
choice = rep(1:4, 10))
# merge both dataframes
df2 <- dplyr::left_join(qqch, df, by = "ID")
# change the values in stype by 1 or 0
for (i in 1:length(df2$ID)){
df2[i, "type"] <- ifelse(df2[i, "type"] == df2[i, "choice"], 1, 0)
}
# format for mlogit
df3 <- mlogit.data(df2, choice = "type", shape = "long", alt.var = "choice")
head(df3)
ID choice type age dum1 dum2
1.1 1 1 FALSE 28 1 1
1.2 1 2 TRUE 28 1 1
1.3 1 3 FALSE 28 1 1
1.4 1 4 FALSE 28 1 1
2.1 2 1 FALSE 31 0 0
2.2 2 2 FALSE 31 0 0
如果我这样做:
mlogit(type ~ age + dum1 + dum2, df3)
我有错误:
Error in solve.default(H, g[!fixed]) : system is computationally singular: reciprocal condition number
除非我们做出更多假设,否则您的数据不适合使用 MNL 模型进行估算。通常,由于您的所有变量都是特定于个体的,并且不会因备选方案(类型)而异,因此无法识别模型。除非我们将它们视为替代性特征,否则您所有的个人特征都将被剔除。听上去,每个专业课程本身都具有意义。在那种情况下,我们可以仅使用常量来估计 MNL 模型,其中常量包含有关使个人选择它的程序的所有内容。
library(mlogit)
df <- data.frame(ID = seq(1, 10),
type = c(2, 3, 4, 2, 1, 1, 4, 1, 3, 2),
age = c(28, 31, 12, 1, 49, 80, 36, 53, 22, 10),
dum1 = c(1, 0, 0, 0, 0, 1, 0, 1, 1, 0),
dum2 = c(1, 0, 1, 1, 0, 0, 1, 0, 1, 0))
现在,为了安全起见,我为每个程序创建了虚拟变量。 type_1
指程序 1,type_2
指程序 2 等
qqch <- data.frame(ID = rep(df$ID, each = 4),
choice = rep(1:4, 10))
# merge both dataframes
df2 <- dplyr::left_join(qqch, df, by = "ID")
# change the values in stype by 1 or 0
for (i in 1:length(df2$ID)){
df2[i, "type"] <- ifelse(df2[i, "type"] == df2[i, "choice"], 1, 0)
}
# Add alternative specific variables (here only constants)
df2$type_1 <- ifelse(df2$choice == 1, 1, 0)
df2$type_2 <- ifelse(df2$choice == 2, 1, 0)
df2$type_3 <- ifelse(df2$choice == 3, 1, 0)
df2$type_4 <- ifelse(df2$choice == 4, 1, 0)
# format for mlogit
df3 <- mlogit.data(df2, choice = "type", shape = "long", alt.var = "choice")
head(df3)
现在我们可以运行模型了。我包括了每个备选方案的虚拟变量,将备选方案 4 作为我的参考水平。仅标识 J-1 个常量,其中 J 是备选方案的数量。在公式的后半部分(在管道运算符之后),我确保删除了模型将创建的所有替代特定常量,并添加了您的个人特定变量,将它们视为替代特定变量。请注意,这仅在您的替代方案(程序)具有意义且不通用时才有意义。
model <- mlogit(type ~ type_1 + type_2 + type_3 | -1 + age + dum1 + dum2,
reflevel = 4, data = df3)
summary(model)
我正在 R 上复制一些 Stata 代码,我想使用同名包中的 mlogit
函数执行多项逻辑回归(我知道有一个 multinom
在 nnet
中的功能,但我不想使用这个)。
我的问题是,要使用 mlogit
,我需要使用 mlogit.data
格式化我的数据,但我不知道如何正确格式化它。将我的数据与文档和 this question 中的示例中使用的数据进行比较,我意识到它们的形式不同。
的确,我使用的数据是这样的:
df <- data.frame(ID = seq(1, 10),
type = c(2, 3, 4, 2, 1, 1, 4, 1, 3, 2),
age = c(28, 31, 12, 1, 49, 80, 36, 53, 22, 10),
dum1 = c(1, 0, 0, 0, 0, 1, 0, 1, 1, 0),
dum2 = c(1, 0, 1, 1, 0, 0, 1, 0, 1, 0))
ID type age dum1 dum2
1 1 2 28 1 1
2 2 3 31 0 0
3 3 4 12 0 1
4 4 2 1 0 1
5 5 1 49 0 0
6 6 1 80 1 0
7 7 4 36 0 1
8 8 1 53 1 0
9 9 3 22 1 1
10 10 2 10 0 0
而他们使用的数据如下:
key altkey A B C D
1 201005131 1 2.6 118.17 117 0
2 201005131 2 1.4 117.11 115 0
3 201005131 3 1.1 117.38 122 1
4 201005131 4 24.6 NA 122 0
5 201005131 5 48.6 91.90 122 0
6 201005131 6 59.8 NA 122 0
7 201005132 1 20.2 118.23 113 0
8 201005132 2 2.5 123.67 120 1
9 201005132 3 7.4 116.30 120 0
10 201005132 4 2.8 118.86 120 0
11 201005132 5 6.9 124.72 120 0
12 201005132 6 2.5 123.81 120 0
如您所见,在他们的案例中,有一列 altkey
详细说明每个 key
的每个类别,还有一列 D
显示选择了哪个选项由人。
但是,我只有一列 (type
) 显示了个人的选择,但没有显示其他备选方案或每个备选方案的其他变量的值。当我尝试申请 mlogit
时,我有:
library(mlogit)
mlogit(type ~ age + dum1 + dum2, df)
Error in data.frame(lapply(index, function(x) x[drop = TRUE]), row.names = rownames(mydata)) : row names supplied are of the wrong length
因此,如何格式化我的数据,使其符合 mlogit
要求的数据类型?
编辑: 按照@edsandorf 的建议,我修改了我的数据框并且 mlogit.data
有效,但现在所有其他解释变量对于每个替代项都具有相同的值。我应该在所选替代项为 0 或 FALSE 的行中将这些变量设置为 0 吗? (事实上 ,有人可以告诉我从我所在的位置到 mlogit
结果的过程,因为我没有得到我估计错误的地方吗?)
我在这里显示的数据(df
)不是我的真实数据。然而,它是完全相同的形式:一列有备选方案的选择(type
),一列有假人和年龄等。
这是我到目前为止所做的程序(我没有将替代项设置为 0):
# create a dataframe with all alternatives for each ID
qqch <- data.frame(ID = rep(df$ID, each = 4),
choice = rep(1:4, 10))
# merge both dataframes
df2 <- dplyr::left_join(qqch, df, by = "ID")
# change the values in stype by 1 or 0
for (i in 1:length(df2$ID)){
df2[i, "type"] <- ifelse(df2[i, "type"] == df2[i, "choice"], 1, 0)
}
# format for mlogit
df3 <- mlogit.data(df2, choice = "type", shape = "long", alt.var = "choice")
head(df3)
ID choice type age dum1 dum2
1.1 1 1 FALSE 28 1 1
1.2 1 2 TRUE 28 1 1
1.3 1 3 FALSE 28 1 1
1.4 1 4 FALSE 28 1 1
2.1 2 1 FALSE 31 0 0
2.2 2 2 FALSE 31 0 0
如果我这样做:
mlogit(type ~ age + dum1 + dum2, df3)
我有错误:
Error in solve.default(H, g[!fixed]) : system is computationally singular: reciprocal condition number
除非我们做出更多假设,否则您的数据不适合使用 MNL 模型进行估算。通常,由于您的所有变量都是特定于个体的,并且不会因备选方案(类型)而异,因此无法识别模型。除非我们将它们视为替代性特征,否则您所有的个人特征都将被剔除。听上去,每个专业课程本身都具有意义。在那种情况下,我们可以仅使用常量来估计 MNL 模型,其中常量包含有关使个人选择它的程序的所有内容。
library(mlogit)
df <- data.frame(ID = seq(1, 10),
type = c(2, 3, 4, 2, 1, 1, 4, 1, 3, 2),
age = c(28, 31, 12, 1, 49, 80, 36, 53, 22, 10),
dum1 = c(1, 0, 0, 0, 0, 1, 0, 1, 1, 0),
dum2 = c(1, 0, 1, 1, 0, 0, 1, 0, 1, 0))
现在,为了安全起见,我为每个程序创建了虚拟变量。 type_1
指程序 1,type_2
指程序 2 等
qqch <- data.frame(ID = rep(df$ID, each = 4),
choice = rep(1:4, 10))
# merge both dataframes
df2 <- dplyr::left_join(qqch, df, by = "ID")
# change the values in stype by 1 or 0
for (i in 1:length(df2$ID)){
df2[i, "type"] <- ifelse(df2[i, "type"] == df2[i, "choice"], 1, 0)
}
# Add alternative specific variables (here only constants)
df2$type_1 <- ifelse(df2$choice == 1, 1, 0)
df2$type_2 <- ifelse(df2$choice == 2, 1, 0)
df2$type_3 <- ifelse(df2$choice == 3, 1, 0)
df2$type_4 <- ifelse(df2$choice == 4, 1, 0)
# format for mlogit
df3 <- mlogit.data(df2, choice = "type", shape = "long", alt.var = "choice")
head(df3)
现在我们可以运行模型了。我包括了每个备选方案的虚拟变量,将备选方案 4 作为我的参考水平。仅标识 J-1 个常量,其中 J 是备选方案的数量。在公式的后半部分(在管道运算符之后),我确保删除了模型将创建的所有替代特定常量,并添加了您的个人特定变量,将它们视为替代特定变量。请注意,这仅在您的替代方案(程序)具有意义且不通用时才有意义。
model <- mlogit(type ~ type_1 + type_2 + type_3 | -1 + age + dum1 + dum2,
reflevel = 4, data = df3)
summary(model)