Tenho um data frame que preciso colocar em formato longo. Aqui está uma versão simplificada do meu data frame:
df <- data.frame("UserID" = c(1:3), "ProdID" = c(1, 1, 2), "A_Q_FaultID_C_1" = c(3, 2, 4), "A_Q_FaultID_C_2" = c(8, 1, 2), "A_Q_FaultID_C_3" = c(4, 3, 9), "A_Q_FaultYear_C_1" = c(1999, 2018, 2012), "A_Q_FaultYear_C_2" = c(2002, 2008, 2024), "A_Q_FaultYear_C_3" = c(2015, 2015, 1997))
A ideia é terminar com um quadro de dados parecido com este, girando por mais tempo com base nos nomes das variáveis com os IDs de usuário e produto como chaves:
df <- data.frame("UserID" = c(1:3, 1:3, 1:3), "ProdID" = c(1, 1, 2, 1, 1, 2, 1, 1, 2), "FaultID" = c(3, 2, 4, 8, 1, 2, 4, 3, 9), "FaultYear" = c(1999, 2018, 2012, 2002, 2008, 2024, 2015, 2015, 1997))
Na realidade, o quadro de dados tem muito mais linhas e muito mais colunas dentro de cada grupo de pivô, mas a convenção geral de nomenclatura para as colunas que desejo que sejam pivotadas por mais tempo é a mesma, ou seja, elas começam com "A_Q_" e terminam com " C [sequência numérica]". Observe que a sequência numérica não é necessariamente apenas um único dígito.
Aqui está minha tentativa usando a função tidyr pivot_longer:
df <- df %>%
pivot_longer(
cols = 3:8,
names_to = c("FaultID", "FaultYear"),
names_pattern = "[a-zA-Z_]+"
)
Isso gera o erro: " regex
deve definir 2 grupos; 0 encontrado.", no entanto, testei essa regex usando os nomes das colunas e str_match e ela extrai tudo, exceto os dígitos finais, identificando exclusivamente dois grupos:
str_match(names(df)[3:8], "[a-zA-Z_]+")
[,1]
[1,] "A_Q_FaultID_C_"
[2,] "A_Q_FaultID_C_"
[3,] "A_Q_FaultID_C_"
[4,] "A_Q_FaultYear_C_"
[5,] "A_Q_FaultYear_C_"
[6,] "A_Q_FaultYear_C_"
O que estou fazendo errado?
Para essa situação, é mais fácil usar
names_to = ".value"
, onde".value"
é um "sentinela" especial que irá girar para múltiplas colunas com base em nomes extraídos decols
. Então, emnames_pattern
, você precisa incluir um padrão regex com um grupo de captura (ou seja,"()"
) que extrai a parte dos nomes das colunas que define as novas colunas.PS - Eu recomendo fortemente usar um auxiliar tidyselect para o
cols
argumento (por exemplo,A_Q_FaultID_C_1:A_Q_FaultYear_C_3
orstarts_with("A_Q_")
) em vez de um intervalo numérico como3:8
. Este último é mais propenso a erros (por exemplo, se o número ou a ordem das colunas mudar, ou apenas por contagens erradas).