将 DF 的结构更改为虚拟

Change structure of DF to dummy

我正在寻找一种改变 DF 结构的方法,以便之后可以使用 beta 回归。 df 目前看起来像这样:

rating   playerID
   0.6         a1
    NA         b2
   0.9         a4
    NA         b5
     0         a3
    NA         b2

我需要让它看起来像这样:

rating   a1   a2   a3   a4   a5   b1   b2   b3   b4   b5
   0.6    1    0    0    0    0    0   -1    0    0    0
   0.9    0    0    0    1    0    0    0    0    0   -1
     0    0    0    1    0    0    0   -1    0    0    0

“bX”变量不需要 -1(1 也可以)。 背后的想法是采用成对的方式(玩家“aX”和“bX”)并将它们编码为虚拟变量,并将玩家“aX”的评分放在同一行。

感谢您的任何想法和意见。

您可以使用 fill()complete() 重组数据,然后将其旋转到宽。

library(dplyr)
library(tidyr)

df %>%
  mutate(value = ifelse(is.na(rating), -1, 1)) %>% 
  fill(rating) %>%
  complete(rating, playerID = paste0(rep(c("a", "b"), each = 5), 1:5)) %>% 
  pivot_wider(names_from = playerID)

# # A tibble: 3 x 11
#   rating    a1    a2    a3    a4    a5    b1    b2    b3    b4    b5
#    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1    0      NA    NA     1    NA    NA    NA    -1    NA    NA    NA
# 2    0.6     1    NA    NA    NA    NA    NA    -1    NA    NA    NA
# 3    0.9    NA    NA    NA     1    NA    NA    NA    NA    NA    -1

数据

df <- structure(list(rating = c(0.6, NA, 0.9, NA, 0, NA), playerID = c("a1", 
"b2", "a4", "b5", "a3", "b2")), row.names = c(NA, -6L), class = "data.frame")

这是一个使用 table 的基础 R 解决方案,假设因子水平 a1b5 已经存在于 playerID:

table(subset(DF, grepl("a", playerID))) -
 table(subset(within(DF, rating <- dplyr::lag(rating)), grepl("b", playerID)))

#>       playerID
#> rating a1 a2 a3 a4 a5 b1 b2 b3 b4 b5
#>    0    0  0  1  0  0  0 -1  0  0  0
#>    0.6  1  0  0  0  0  0 -1  0  0  0
#>    0.9  0  0  0  1  0  0  0  0  0 -1