Как преобразовать DataFrame в широкий формат с заданными парами столбцов

Вопрос или проблема

У меня есть следующий расплавленный образец датафрейма:

df_melted <- data.frame(ID = c(21, 21, 21, 21, 49, 49, 49, 49), instance = c(1, 1, 1, 1, 1, 1, 2, 2), variable = c("causeofdeath", "deathdate", "dob", "gender", "causeofdeath", "deathdate", "deathdate", "causeofdeath"), value_temp = c("BLANK", "MM/DD/YYYY", "BLANK", "F", "BLANK", "BLANK", "MM/DD/YYYY", "BLANK"))

df_melted

И следующий файл сопоставления, который я хочу в конечном итоге использовать для получения новых значений:

df_map <- data.frame(var_name_1 = c("causeofdeath", "causeofdeath", "dob"), val_1 = c("BLANK", "BLANK", "MM/DD/YYYY"), var_name_2 = c("deathdate", "deathdate", "gender"), val_2 = c("MM/DD/YYYY", "BLANK", "F"), new_var_name = c("ida", "idf", "ids"), new_val = c("T60", "T55", "T67"))

df_map

Как я могу преобразовать df_melted так, чтобы он имел ту же конкретную структуру, что и показано в df_map?, т.е.

df_wanted

Я пытался использовать pivot_wider(), но безуспешно

Вы можете попробовать pivot_wider после добавления некоторых вспомогательных столбцов, например, p и grp

df_melted %>%
    mutate(p = rep(1:2, length.out = n()), grp = ceiling(row_number() / 2)) %>%
    pivot_wider(
        names_from = p,
        values_from = c(variable, value_temp),
        id_cols = c(ID, instance, grp),
        names_vary = "slowest"
    ) %>%
    select(-grp)

и вы получите

# A tibble: 4 × 6
     ID instance variable_1   value_temp_1 variable_2   value_temp_2
  <dbl>    <dbl> <chr>        <chr>        <chr>        <chr>
1    21        1 causeofdeath BLANK        deathdate    MM/DD/YYYY
2    21        1 dob          BLANK        gender       F
3    49        1 causeofdeath BLANK        deathdate    BLANK
4    49        2 deathdate    MM/DD/YYYY   causeofdeath BLANK

Ответ или решение

Чтобы преобразовать ваш размеченный датафрейм df_melted в широкий формат на основе заданной пары столбцов, вы можете использовать функцию pivot_wider() из пакета tidyverse в R. Ваша задача заключается в том, чтобы правильно создать новые столбцы, используя ключи из df_map для сопоставления и замены значений.

Вот шаги, которые вам нужно выполнить для достижения этой задачи:

  1. Создадим вспомогательные столбцы, которые помогут нам в преобразовании. Мы добавим столбцы p и grp, которые помогут сгруппировать данные.

  2. Используем функцию pivot_wider(), чтобы преобразовать данные в широкий формат.

  3. Затем сопоставим значения с вашим сопоставляющим файлом df_map, чтобы получить новые значения.

Вот пример кода, который выполняет описанные шаги:

library(dplyr)
library(tidyr)

# Исходные данные
df_melted <- data.frame(ID = c(21, 21, 21, 21, 49, 49, 49, 49), 
                         instance = c(1, 1, 1, 1, 1, 1, 2, 2), 
                         variable = c("causeofdeath", "deathdate", "dob", "gender", "causeofdeath", "deathdate", "deathdate", "causeofdeath"), 
                         value_temp = c("BLANK", "MM/DD/YYYY", "BLANK", "F", "BLANK", "BLANK", "MM/DD/YYYY", "BLANK"))

df_map <- data.frame(var_name_1 = c("causeofdeath", "causeofdeath", "dob"), 
                     val_1 = c("BLANK", "BLANK", "MM/DD/YYYY"), 
                     var_name_2 = c("deathdate", "deathdate", "gender"), 
                     val_2 = c("MM/DD/YYYY", "BLANK", "F"), 
                     new_var_name = c("ida", "idf", "ids"), 
                     new_val = c("T60", "T55", "T67"))

# Шаг 1: Добавление вспомогательных колонок
df_wide <- df_melted %>%
    mutate(p = rep(1:2, length.out = n()), 
           grp = ceiling(row_number() / 2)) %>%
    pivot_wider(
        names_from = p,
        values_from = c(variable, value_temp),
        id_cols = c(ID, instance, grp),
        names_vary = "slowest"
    ) %>%
    select(-grp)

# Шаг 2: Преобразование, чтобы получить новые значения
df_final <- df_wide %>%
    left_join(df_map, by = c("variable_1" = "var_name_1", "value_temp_1" = "val_1")) %>%
    left_join(df_map, by = c("variable_2" = "var_name_2", "value_temp_2" = "val_2")) %>%
    select(ID, instance, new_var_name = coalesce(new_var_name.x, new_var_name.y),
           new_val = coalesce(new_val.x, new_val.y)) %>%
    distinct()

# Результат
print(df_final)

В этом коде:

  • Мы создаем два новых столбца (variable_1 и value_temp_1 для первой группы и variable_2 и value_temp_2 для второй группы) путем применения pivot_wider().
  • Затем сливаем полученные данные с df_map, чтобы назначить новые имена и значения.
  • С помощью функции coalesce() мы выбираем значения из обоих замыкающихся столбцов, чтобы получить окончательный результат в df_final.

Эти шаги позволят вам преобразовать ваш исходный датафрейм в необходимый широкий формат с использованием ваших сопоставлений. Убедитесь, что уже установлены и загружены соответствующие пакеты (например, dplyr и tidyr).

Оцените материал
Добавить комментарий

Капча загружается...