Tenho um dataframe df de visitas de pacientes estruturado no seguinte formato:
EU IA | número_de_visita | variável | valor |
---|---|---|---|
34 | 1 | altura | curto |
34 | 1 | peso | sobre |
34 | 1 | cor dos olhos | marrom |
34 | 1 | cor_de_cabelo | marrom |
89 | 1 | peso | normal |
89 | 1 | altura | curto |
89 | 2 | altura | curto |
89 | 2 | peso | sobre |
df <- data.frame(ID = c(34, 34, 34, 34, 89, 89, 89, 89), visit_number = c(1, 1, 1, 1, 1, 1, 2, 2), variable = c("height", "weight", "eye_color", "hair_color", "weight", "height", "height", "weight"), value = c("short", "over", "brown", "brown", "normal", "short", "short", "over"))
Então, para a visita nº 1, o paciente 34 teve sua altura, peso, cor dos olhos e cabelo anotados. O paciente 89 teve duas visitas registrando sua altura e peso.
Tenho um arquivo de mapeamento que mostra um par de variáveis e valores que resulta em um novo valor que eu gostaria de extrair para cada par relevante:
var_1 | val_1 | var_2 | val_2 | novo_nome_var | novo_val |
---|---|---|---|---|---|
altura | curto | peso | normal | saúde | média |
altura | curto | peso | sobre | saúde | avisar |
cor dos olhos | marrom | cor_de_cabelo | marrom | tez | monocromático |
cor dos olhos | azul | cor_de_cabelo | loiro | tez | contraste |
mapping <- data.frame( var_1= c("height", "height", "eye_color", "eye_color"), val_1 = c("short", "short", "brown", "blue"), var_2 = c("weight", "weight", "hair_color", "hair_color"), val_2 = c("normal", "over", "brown", "blonde"), new_var_name = c("health", "health", "complexion", "complexion"), new_val = c("average", "warn", "monochrome", "contrast"))
Então, esse arquivo de mapeamento mostra que se a altura de um paciente for baixa e seu peso for normal, eu gostaria de criar uma variável de saúde definida como "média". Se a altura dele for baixa e seu peso for acima do normal, eu gostaria que esse indicador de saúde fosse "aviso", e assim por diante, como os outros pares nas linhas subsequentes mostram.
Qual seria a melhor maneira de fazer isso? Podemos assumir que todos os pares serão cobertos no dataframe de mapeamento e também podemos assumir que não haverá pares incompletos nos dados.
Esse é um tipo de método de força bruta que pode causar problemas se você tiver mais de dezenas de variáveis, mas espero que funcione bem em muitas situações.
Primeiro, eu expando os dados para que cada linha seja correspondida com todas as outras linhas na visita do mesmo paciente. Isso pode ficar grande se houver muitas variáveis. Então esses pares são correspondidos com a tabela de mapeamento, onde apenas os pares rotulados são gerados.
Isso poderia ser feito duas vezes mais eficiente em termos de memória se pudéssemos garantir que as variáveis de mapeamento fossem sempre classificadas alfabeticamente, com var_1 < var_2. Então poderíamos limitar a primeira junção aos pares onde variável.x < variável.y, resultando em metade das combinações para procurar na segunda junção.
Resultado