Tenho o seguinte dataframe de exemplo:
df <- data.frame(
record_id = c(1, 1, 1, 2, 2, 3, 3, 3),
instance = c(NA, NA, 2, NA, 1, 2, NA, NA),
A = c(10, NA, NA, 20, 25, NA, 30, NA),
B = c(NA, 5, NA, NA, 5, 15, NA, 15),
C = c(NA, NA, 3, NA, 5, 20, NA, 20),
D = c(NA, NA, NA, 25, 25, 30, NA, 30)
)
record_id instance A B C D
1 1 NA 10 NA NA NA
2 1 NA NA 5 NA NA
3 1 2 NA NA 3 NA
4 2 NA 20 NA NA 25
5 2 1 25 5 5 25
6 3 2 NA 15 20 30
7 3 NA 30 NA NA NA
8 3 NA NA 15 20 30
Se a instância for NA, quero que as linhas do mesmo record_id sejam recolhidas em uma linha. No meu dataframe, não haverá dois ou mais valores na mesma coluna para o mesmo record_id e grupo de instâncias NA.
Em outras palavras, eu gostaria de obter:
record_id instance A B C D
1 1 NA 10 5 NA NA
2 1 2 NA NA 3 NA
3 2 NA 20 NA NA 25
4 2 1 25 5 5 25
5 3 2 NA 15 20 30
6 3 NA 30 15 20 30
Como posso fazer isso?
Uma opção R básica com
aggregate
dá
Você poderia fazer:
que dá:
Observação: este código pressupõe que você tenha apenas uma linha por record_id com a mesma instância (que não seja NA).
ATUALIZAÇÃO: Conforme discutido nos comentários, uma alternativa seria usar
reframe
:que dá:
ThomasIsCoding já forneceu uma excelente versão base R disto. Uma variante data.table é:
Uma opção R base usando
by
,e um usando
data.table
.Aqui estão mais dois:
a primeira abordagem é semelhante à abordagem do @r2evans, mas usando
reduce
junto comcoalesce
.Segundo usando uma função personalizada:
saída: