假设我有一些人选择了几个选项。每个人有一行数据,但我想要每个人和选项都有一行数据。比如,如果有10个人,每个人有3个选项,那么现在有10行数据,而我希望有30行。
其他所有变量都应该复制到新的行中。例如,如果有一个性别变量,那么它应该在 ID 内是恒定的。(我按照这种方式设置我的数据以便使用 mnlogit
进行分析。)
这似乎是两个 tidyr
函数 complete
和 fill
设计用来解决的问题。举个简单的例子:
library(lubridate)
library(tidyr)
dat <- data.frame(
id = 1:3,
choice = 5:7,
c = c(9, NA, 11),
d = ymd(NA, "2015-09-30", "2015-09-29")
)
dat %>%
complete(id, choice) %>%
fill(everything())
# Source: local data frame [9 x 4]
#
# id choice c d
# (int) (int) (dbl) (time)
# 1 1 5 9 <NA>
# 2 1 6 9 <NA>
# 3 1 7 9 <NA>
# 4 2 5 9 <NA>
# 5 2 6 9 2015-09-30
# 6 2 7 9 2015-09-30
# 7 3 5 9 2015-09-30
# 8 3 6 9 2015-09-30
# 9 3 7 11 2015-09-29
但是这种方法存在一些问题——d的值被正确地向下传递了,但是ID为1的c的值替换了ID为2的(正确的)NA值。
我可以尝试一个解决方法,比如用999替换所有缺失的值,运行complete
和fill
,然后再用NA替换999。(如果我选择这条路线,我认为我必须将日期变量转换为字符变量,然后再转换回来。) 但也许在这里有人知道使用tidyr
的简洁方法?
编辑: 这里期望的输出是:
# Source: local data frame [9 x 4]
#
# id c d choice
# (int) (dbl) (time) (int)
# 1 1 9 <NA> 5
# 2 1 9 <NA> 6
# 3 1 9 <NA> 7
# 4 2 NA 2015-09-30 5
# 5 2 NA 2015-09-30 6
# 6 2 NA 2015-09-30 7
# 7 3 11 2015-09-29 5
# 8 3 11 2015-09-29 6
# 9 3 11 2015-09-29 7
mlogit
包含一个名为mlogit.data
的函数,可以解决这个问题。mlogit.data(dat, choice = "choice", shape = "wide")
也会产生所需的结果。我知道我要求使用tidyr
的解决方案,但是为了未来的读者,我认为包括这个解决方案也可能有帮助。 - Jake Fisher