R: как отформатировать мои данные для полиномиального логита?

Я воспроизвожу код Stata на R и хочу выполнить полиномиальную логистическую регрессию с функцией mlogit из одноименного пакета (я знаю, что в nnet есть функция multinom, но я не хочу использовать эту один).

Моя проблема в том, что для использования mlogit мне нужно, чтобы мои данные были отформатированы с использованием mlogit.data, и я не могу понять, как правильно их форматировать. Сравнение моих данных с данными, используемыми в примерах в документации и в этот вопрос, я понимаю, что он не в той же форме.

Действительно, данные, которые я использую, выглядят так:

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)

Ошибка в data.frame(lapply(index, function(x) x[drop = TRUE]), row.names = rownames(mydata)) : предоставленные имена строк имеют неправильную длину

Следовательно, как я могу отформатировать свои данные, чтобы они соответствовали типу данных, который требует mlogit?

Редактировать: следуя советам @edsandorf, я изменил свой фрейм данных, и mlogit.data работает, но теперь все остальные независимые переменные имеют одинаковое значение для каждой альтернативы. Должен ли я установить эти переменные в 0 в строках, где выбранная альтернатива равна 0 или FALSE? (на самом деле, может ли кто-нибудь показать мне процедуру от того, где я нахожусь, до результатов 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

If I do :

mlogit(type ~ age + dum1 + dum2, df3)

У меня ошибка:

Ошибка вsolve.default(H, g[!fixed]): система вычислительно сингулярна: взаимное число условия


person bretauv    schedule 05.12.2019    source источник
comment
Чтобы применить полиномиальную логит-модель, вам нужна информация о выбранных и невыбранных альтернативах. Похоже, вы можете наблюдать только выбранные альтернативы. Можно ли предположить, что все стояли перед выбором между одними и теми же альтернативами? Потому что можно было бы воссоздать невыбранных на основе выбора всех остальных.   -  person edsandorf    schedule 06.12.2019
comment
@edsandorf да, у всех был выбор, моя ошибка. На самом деле я думал, что функция mlogit в R работает так же, как и в Stata.   -  person bretauv    schedule 06.12.2019
comment
поэтому я должен добавить каждую альтернативу для каждого идентификатора и добавить столбец, указывающий, какая альтернатива была выбрана?   -  person bretauv    schedule 06.12.2019
comment
да. Таким образом, у вас будет один столбец с указанием лица, принимающего решения, один с указанием случая выбора (если вы наблюдаете более одного выбора на одного лица, принимающего решения), один с указанием каждой доступной альтернативы и один с указанием выбора. Тогда ваши данные будут в так называемом длинном формате. Вам все еще нужно запустить mlogit.data(), чтобы добавить дополнительные атрибуты к данным, которые требуются функции mlogit().   -  person edsandorf    schedule 06.12.2019
comment
@edsandorf, вы можете проверить правку (я добавил вопрос)?   -  person bretauv    schedule 06.12.2019
comment
Нет, вы не хотите устанавливать ни одно из значений равным нулю. Как вы определили невыбранные альтернативы для каждого человека? Почему они должны быть точно такими же, как избранный? Очень трудно сказать что-то еще, не видя данных (зная природу данных). Пример, который вы привели, основан на ваших реальных данных?   -  person edsandorf    schedule 06.12.2019
comment
Данные, которые я показываю здесь (df), не являются моими истинными данными. Однако это точно такая же форма: столбец с выбором альтернативы (type), столбцы с пустышками и возрастом и т. д. Я отредактировал свой пост, чтобы показать, что я сделал до сих пор.   -  person bretauv    schedule 06.12.2019
comment
В этом конкретном случае вы получаете ошибку, потому что обратного гессиана не существует. Это вызвано отсутствием различий в ваших данных, т. е. ваши выбранные и невыбранные альты одинаковы. Позвольте мне задать еще несколько уточняющих вопросов, увидев, как вы генерируете свои данные. 1) Является ли возраст по отношению к типу, т.е. альтернативному специфическому или по отношению к ЛПР, т.е. индивидуальному? 2) мой предыдущий вопрос о типах. Например, тип 2 всегда один и тот же, независимо от лица, принимающего решения? 3) Могут ли все лица, принимающие решения, выбирать между всеми типами?   -  person edsandorf    schedule 06.12.2019
comment
1) возраст индивидуален: он варьирует у разных людей, но не зависит от выбранного типа. dum1 и dum2 работают одинаково: они различаются у разных людей, но не у разных вариантов выбора; 2) немного больше контекста: каждый человек делает выбор из 4-х профессиональных программ. Таким образом, каждый тип одинаков независимо от лиц/лиц, принимающих решения; 3) каждое лицо, принимающее решение, может выбрать любую из 4 альтернатив. Тип переменной отражает выбор, сделанный каждым лицом, принимающим решение.   -  person bretauv    schedule 06.12.2019


Ответы (1)


Ваши данные плохо поддаются оценке с использованием модели 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)
person edsandorf    schedule 07.12.2019
comment
это прекрасно, спасибо за советы и четкие объяснения! если вы знаете, как упорядочить результаты, чтобы они были сгруппированы по альтернативам, не могли бы вы добавить это в свой пост? - person bretauv; 07.12.2019