Использование циклов for, while, tidyverse или пакетов для создания набора данных с характеристиками, соответствующими предыдущему (выборка)

Я работаю с панельными данными. Мы оценивали детей в 2019 и 2020 годах. Поэтому у меня есть два набора данных (2019 и 2020 годы), и я хочу создать третий набор данных, соответствующий данным из второго набора данных (2020 года), который соответствует характеристикам первого набора данных (2019 года). Это В третьем наборе данных будет меньше участников, но они будут иметь те же характеристики, что и их «сверстники» из 2019 года. Таким образом, соотношение мальчиков и девочек будет примерно таким же, как в 2019 году, возраст матери будет примерно таким же и т. д.

Пример:

Код:

df_2019 = structure(list(asqse_quest = c(24, 24, 24, 24, 24, 24, 24, 24, 
                                         24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
                                         24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
                                         24, 24, 24, 24, 24, 24, 24, 24, 24, 24), year_completed_cat = structure(c(2L, 
                                                                                                                   2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                                                                                                   2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                                                                                                   2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                                                                                                   2L), levels = c("18", "19", "20", "21", "22", "23", "24"), class = "factor"), 
                         sex_male = c(1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 
                                      1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 
                                      0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0), momage = c(36, 
                                                                                                  39, 22, 20, 29, 40, 31, 37, 29, 38, 24, 35, 32, 30, 32, 31, 
                                                                                                  29, 21, 28, 29, 40, 21, 38, 29, 28, 33, 25, 25, 30, 29, 25, 
                                                                                                  27, 28, 31, 24, 28, 35, 29, 17, 35, 32, 29, 27, 24, 29, 25, 
                                                                                                  28, 24, 21, 26), momed = c(4, 4, 2, 2, 4, 3, 2, 3, 2, 4, 
                                                                                                                             3, 4, 4, 4, 4, 4, 3, 4, 3, 4, 4, 2, 2, 4, 4, 4, 4, 4, 4, 
                                                                                                                             4, 2, 4, 3, 3, 3, 3, 4, 4, 2, 4, 4, 3, 2, 2, 3, 4, 4, 3, 
                                                                                                                             2, 4), income = c(4, 4, 2, 3, 4, 1, 2, 5, 4, 4, 5, 4, 4, 
                                                                                                                                               4, 4, 4, 4, 2, 3, 3, 4, 2, 3, 4, 4, 4, 5, 4, 3, 3, 4, 4, 
                                                                                                                                               3, 4, 1, 4, 2, 4, 3, 4, 4, 3, 4, 3, 4, 4, 4, 3, 4, 4)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                                                                           -50L))


df_2020 = structure(list(asqse_quest = c(24, 24, 24, 24, 24, 24, 24, 24, 
                                         24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
                                         24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
                                         24, 24, 24, 24, 24, 24, 24, 24, 24, 24), year_completed_cat = structure(c(3L, 
                                                                                                                   3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
                                                                                                                   3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
                                                                                                                   3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
                                                                                                                   3L), levels = c("18", "19", "20", "21", "22", "23", "24"), class = "factor"), 
                         sex_male = c(1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 
                                      0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 
                                      1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1), momage = c(23, 
                                                                                                  26, 33, 34, 29, 26, 23, 29, 40, 36, 33, 18, 31, 31, 31, 32, 
                                                                                                  34, 35, 29, 37, 19, 30, 33, 25, 32, 35, 37, 27, 23, 29, 28, 
                                                                                                  26, 30, 27, 38, 28, 29, 39, 26, 25, 29, 39, 35, 32, 20, 38, 
                                                                                                  31, 27, 28, 23), momed = c(2, 4, 4, 3, 4, 3, 2, 2, 3, 4, 
                                                                                                                             1, 2, 2, 4, 4, 4, 4, 2, 4, 4, 2, 4, 4, 4, 2, 4, 4, 2, 4, 
                                                                                                                             2, 1, 4, 3, 2, 4, 4, 4, 2, 4, 2, 4, 4, 4, 4, 2, 4, 4, 4, 
                                                                                                                             4, 1), income = c(2, 4, 4, 4, 4, 5, 3, 2, 2, 4, 1, 3, 4, 
                                                                                                                                               5, 1, 4, 3, 1, 4, 5, 5, 4, 4, 4, 3, 4, 4, 2, 4, 5, 1, 4, 
                                                                                                                                               4, 1, 4, 4, 4, 4, 3, 4, 4, 4, 5, 4, 2, 4, 4, 4, 4, 4)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                                                                           -50L))

Created on 2024-07-12 with reprex v2.1.0

Я думаю, вам нужна функция matchit из пакета MatchIt.

Edward 13.07.2024 09:44

Да, ты можешь вести меня? Я сам попробовал пакет, но безуспешно.

Luis 13.07.2024 10:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете попробовать пакет MatchIt, в котором есть функция, выполняющая сопоставление оценок склонности.

Сначала мы объединяем два набора данных с помощью bind_rows, присваивая идентификатор, чтобы различать два набора данных:

library(dplyr)

data <- bind_rows(df_2019, df_2020, .id = "year") |>
  mutate(year=+(year==1)) # 1=2019 (treated), 0=2020 (controls)

Строки, соответствующие году == 1, являются обработанными вами (из данных за 2019 год), а год == 0 соответствует вашим элементам управления (из данных за 2020 год).

Чтобы найти элементы управления, которые максимально соответствуют обработанному, мы можем использовать функцию matchit. Существует несколько аргументов, и для краткости мы будем использовать значения по умолчанию.

library(MatchIt)

Сначала мы попытаемся точно сопоставить полные годы, пол и возраст матери и посмотрим, повезет ли нам это.

match_obj <- matchit(year ~ asqse_quest+year_completed_cat+sex_male+momage+momed+income,
                     data = data, 
                     exact= ~ year_completed_cat+sex_male+momage,
                     replace = FALSE)

#Error in `matchit()`:
#! No matches were found.

Неудивительно, поскольку два набора данных совершенно не совпадают по завершенным годам. Давайте сделаем наше условие соответствия менее строгим.

match_obj <- matchit(year ~ asqse_quest+year_completed_cat+sex_male+momage+momed+income,
                     data = data, 
                     exact= ~ sex_male+momage,
                     replace = FALSE)

На этот раз ошибки нет, но мы получили предупреждение

#Warning message:
#Fewer control units than treated units in some `exact` strata; not all treated units will get a match. 

Это нормально. Теперь подведем итоги.

summary(match_obj)
...
Sample Sizes:
          Control Treated
All            50      50
Matched        25      25
Unmatched      25      25
Discarded       0       0

В выводе говорится, что мы нашли 25 элементов управления из исходных 50. Приведена и другая полезная информация, но для краткости я ее опустил. Теперь используйте match.data, чтобы получить спички вместе с исходной обработкой.

matched_data <- match.data(match_obj)

Теперь мы просто отфильтровываем обработанные элементы, и у нас остаются соответствующие элементы управления:

df_2020_new <- filter(matched_data, year==0)
head(df_2020_new)

   asqse_quest year_completed_cat sex_male momage momed income
1           24                 20        1     23     2      2
2           24                 20        1     26     4      4
3           24                 20        1     33     4      4
4           24                 20        1     34     3      4
5           24                 20        0     29     4      4
6           24                 20        1     26     3      5
7           24                 20        0     23     2      3
8           24                 20        1     29     2      2
9           24                 20        0     40     3      2
10          24                 20        1     36     4      4

Посетите страницу справки matchit, чтобы узнать, как можно изменить методы сопоставления. Здесь слишком много подробностей, но это основная идея.

Спасибо. Вы были лучше, чем расширенная функция gpt. Невероятно. Два небольших вопроса. (1) Могу ли я иметь больше лет и сопоставлять их соответствующим образом (например, запустить anova, чтобы проверить, отличается ли возраст матери и т. д.) (2) Можно ли связать окончательный фрейм данных с детьми из 2019, 2020 г. (и т. д.) с такими же характеристиками? Удивительный. Спасибо

Luis 13.07.2024 21:03

1. Да, конечно. Просто используйте bind_rows еще раз и позвоните aov(year~mage, data=data). 2. Да, принцип тот же, что я изложил.

Edward 14.07.2024 01:33

спасибо за Ваш ответ. Я не хочу редактировать сообщение, потому что ваше решение работает очень хорошо для двух наборов данных. Однако не могли бы вы пересмотреть для меня следующий код? Мне интересно, где ошибка. Еще раз спасибо.

Luis 14.07.2024 02:50

код: df_21 <- df %>% filter(year_c == "21") %>% filter(qust == "24") matched_data <- matched_data %>% select(-c(distance, weights, subclass)) #matched data is the result of previous mtching #merge data <- bind_rows(matched_data, df_2021, .id = "year") |> mutate(year=+(year==1)) # 1=2019+2020 (trt), 0=2021 (control) match_obj <- matchit(year ~ asqse_quest+year_completed_cat+sex_male+momage+momed+income_‌​poor, data = data, exact= ~ momed+income_poor, method = "optimal") matched_data <- match.data(match_obj)

Luis 14.07.2024 02:51

Что такое сообщение об ошибке? И мне будет сложно это узнать без ваших df данных. Возможно, лучше задать еще один вопрос.

Edward 14.07.2024 15:21

Другие вопросы по теме