#r #dplyr #tidyverse #tidyr
#r #dplyr #tidyverse #tidyr
Вопрос:
У меня есть фрейм данных, подобный:
library(tidyverse)
df_mess <- tibble::tribble(
~id, ~value, ~answer_text,
123, 25, "age",
123, NA, "female",
234, 29, "age",
234, NA, "male",
345, 14, "age",
345, NA, "female"
)
Я хотел бы изменить форму таким образом, чтобы иметь «аккуратные» данные, то есть по 1 строке для каждого наблюдения.
df <- tibble::tribble(
~id, ~age, ~sex,
123, 25, "female",
234, 29, "male",
345, 14, "female"
)
Я попробовал версию gather
/ spread
, но мне не повезло.
Приветствуется любая зацепка.
Комментарии:
1. Привет @xxxvinxxx. Я просто хотел проверить и посмотреть, решил ли предоставленный ответ вашу проблему. Если нет, не могли бы вы рассказать нам, почему этого не произошло? Спасибо!
Ответ №1:
Вот решение с распределением и сбором. spread
Будут получены все переменные типа age
, где имя переменной отображается в столбце answer_text. Если значения переменной находятся в столбце answer_text (например, sex в данном случае), вам нужно будет gather
вернуть их обратно, как показано ниже.
Чтобы заставить столбец sex работать, я изменил NAs
in value
на -99. Однако вы могли бы использовать любое значение. Если вы распространяете без чего-либо в value
столбце, это будет отображаться как NA
в столбцах female
и male
, которые создаются на основе распространения.
df_mess[is.na(df_mess)] <- -99
df_mess %>%
spread(answer_text, value) %>%
gather(sex, temp, female, male, na.rm = TRUE) %>%
select(-temp)
вывод
# A tibble: 3 x 3
id age sex
<dbl> <dbl> <chr>
1 123 25 female
2 345 14 female
3 234 29 male
Пример с большим количеством переменных и допустимой NA
в size
переменной для id
123.
df_mess <- tibble::tribble(
~id, ~value, ~answer_text,
123, 25, "age",
123, NA, "female",
234, 29, "age",
234, NA, "male",
345, 14, "age",
345, NA, "female",
123, NA, "brown",
234, NA, "blonde",
345, NA, "black",
123, NA, "size",
234, 30, "size",
345, 40, "size",
)
df_mess[is.na(df_mess)] <- -99
df_clean <- df_mess %>%
spread(answer_text, value) %>%
gather(sex, temp, female, male, na.rm = TRUE) %>%
select(-temp) %>%
gather(hair, temp, black:brown, na.rm = TRUE) %>%
select(-temp)
df_clean[df_clean == -99] <- NA
df_clean
вывод
id age size sex hair
<dbl> <dbl> <dbl> <chr> <chr>
1 345 14 40 female black
2 234 29 30 male blonde
3 123 25 NA female brown
Ответ №2:
Если структура ваших данных всегда одинакова, я бы сделал что-то вроде:
df_mess$new <- lead(df_mess$answer_text)
df_mess <- subset(df_mess,df_mess$value>0)
но это возможное решение только для этого конкретного случая.