Я работаю с панельными данными. Мы оценивали детей в 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, в котором есть функция, выполняющая сопоставление оценок склонности.
Сначала мы объединяем два набора данных с помощью 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 г. (и т. д.) с такими же характеристиками? Удивительный. Спасибо
1. Да, конечно. Просто используйте bind_rows
еще раз и позвоните aov(year~mage, data=data)
. 2. Да, принцип тот же, что я изложил.
спасибо за Ваш ответ. Я не хочу редактировать сообщение, потому что ваше решение работает очень хорошо для двух наборов данных. Однако не могли бы вы пересмотреть для меня следующий код? Мне интересно, где ошибка. Еще раз спасибо.
код: 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)
Что такое сообщение об ошибке? И мне будет сложно это узнать без ваших df
данных. Возможно, лучше задать еще один вопрос.
Я думаю, вам нужна функция
matchit
из пакета MatchIt.