我正在使用 Bradley-Terry 模型对网球比赛的结果进行建模,但遇到了以下错误。当我跑步时:
library(BradleyTerry2)
matches <- read.csv("data/matches.csv")
model <- BTm(cbind(wins1,
wins2),
player1, player2, data=matches)
model
我收到错误消息:
Error in Diff(player1, player2, formula, id, data, separate.ability, refcat, :
'player1$..' and 'player2$..' must be factors with the same levels
数据框“匹配”具有这种格式(可重现的小示例)。
玩家1 | 玩家2 | 胜1 | 赢2 |
---|---|---|---|
阿加西 | 费德勒 | 0 | 6 |
阿加西 | 休伊特 | 1 | 0 |
阿加西 | 罗迪克 | 1 | 0 |
费德勒 | 亨曼 | 3 | 1 |
费德勒 | 休伊特 | 9 | 0 |
费德勒 | 罗迪克 | 5 | 0 |
亨曼 | 休伊特 | 0 | 2 |
亨曼 | 罗迪克 | 1 | 1 |
休伊特 | 罗迪克 | 3 | 2 |
...等等。任何出现在player1中的名字都会出现在player2中。
我不明白为什么player1和player2的因子有不同的级别?我尝试使用
as.factor
将它们设置为因子,但这不起作用。我还尝试删除 data=matches
并使用 matches$wins1
等作为 BTm
函数的参数,但这也不起作用。现在我有点卡住了,所以欢迎任何想法!谢谢你:)
看看第一列和第二列中有什么。
因子在内部编码为从 1 开始的连续整数。下面我
unclass
每个因子都是为了获得它们的内部表示。
player1
有两个值,1 和 2;player2
有两个值,1 和 2;player1
中,级别"Rafael Nadal"
为第1级,其值为1;player2
中,级别 "Rafael Nadal"
是第二个,其值为 2。这是因为每一列都是独立的因素,与其他列没有关系。
lapply(matches[1:2], unclass)
#> $player1
#> [1] 2 2 1
#> attr(,"levels")
#> [1] "Rafael Nadal" "Roger Federer"
#>
#> $player2
#> [1] 2 1 1
#> attr(,"levels")
#> [1] "Andy Murray" "Rafael Nadal"
创建于2023年11月14日
解决方案是获取所有列的所有唯一值,并在创建因子时使用这些唯一值作为级别。
在第一条指令后面的代码中,将所有唯一值作为字符串获取。然后使用这些字符串作为其级别创建因子列。
lvls <- matches[1:2] |> unlist() |> as.character() |> unique()
matches[1:2] <- lapply(matches[1:2], factor, levels = lvls)
# check that now "Rafael Nadal" is always value 2
lapply(matches[1:2], unclass)
#> $player1
#> [1] 1 1 2
#> attr(,"levels")
#> [1] "Roger Federer" "Rafael Nadal" "Andy Murray"
#>
#> $player2
#> [1] 2 3 3
#> attr(,"levels")
#> [1] "Roger Federer" "Rafael Nadal" "Andy Murray"
创建于2023年11月14日
matches <- structure(list(
player1 = structure(c(2L, 2L, 1L), levels = c("Rafael Nadal", "Roger Federer"), class = "factor"),
player2 = structure(c(2L, 1L, 1L), levels = c("Andy Murray", "Rafael Nadal"), class = "factor"),
wins1 = c(3L, 5L, 4L), wins2 = c(2L, 2L, 3L)),
class = "data.frame", row.names = c(NA, -3L))
创建于2023年11月14日
as.factor()
和
player1
周围使用
player2
。