Можете ли вы использовать несколько условий в функции match () — R

#r

#r

Вопрос:

Я пытаюсь составить график избыточных смертей на 2020 год по сравнению с подтвержденными смертями от covid-19.

У меня есть 2 фрейма данных, один x_worldwide_weekly_deaths (covid-19), а другой содержит избыточные смерти, я хочу добавить столбец избыточных смертей в x_worldwide_weekly_deaths и сопоставить как по коду страны ISO3, так и по номеру недели;

Не каждая страна отслеживает избыточные смерти, поэтому я хочу, чтобы те, которые не входят в исходное избыточное значение df, имели значение NA

Аналогично, не все страны, которые отслеживают избыточные случаи смерти, являются актуальными, у некоторых есть данные за 37 недель, у других может быть только 24, поэтому мне также нужны значения NA для отсутствующих недель

Используя приведенное ниже, я прошел половину пути, страны, не включенные в исходный список, имеют NA, а те, которые имеют значение, однако он использует только первое значение, а не меняет общее количество за неделю

 x_worldwide_weekly_death_values["excess_2020"] <- excess_death_2020$DTotal[match(x_worldwide_weekly_death_values$ISO3,
                                                         excess_death_2020$ISO3)] 
  

Пример данных, отсутствующих в исходном файле excess_death_2020, в которые были успешно добавлены NA

  ISO3  administrative_~ population pop_density_km2 week_number weekly_deaths date       excess_2020
   <chr> <chr>                 <int> <chr>                 <dbl>         <dbl> <date>           <dbl>
 1 AFG   Afghanistan        37172386 56.937760009803           1             0 2020-01-06          NA
 2 AFG   Afghanistan        37172386 56.937760009803           2             0 2020-01-13          NA
 3 AFG   Afghanistan        37172386 56.937760009803           3             0 2020-01-20          NA

  

dput() для вышеуказанного:

 dput(x_worldwide_weekly_death_values[1:3,])
structure(list(ISO3 = c("AFG", "AFG", "AFG"), administrative_area_level_1 = c("Afghanistan", 
"Afghanistan", "Afghanistan"), population = c(37172386L, 37172386L, 
37172386L), pop_density_km2 = c("56.937760009803", "56.937760009803", 
"56.937760009803"), week_number = c(1, 2, 3), weekly_deaths = c(0, 
0, 0), date = structure(c(18267, 18274, 18281), class = "Date"), 
    excess_2020 = c(NA_real_, NA_real_, NA_real_)), row.names = c(NA, 
-3L), class = c("tbl_df", "tbl", "data.frame"))
  

По сравнению с Австрией, где значение недели 1 было добавлено ко всем ячейкам

   ISO3  administrative_a~ population pop_density_km2 week_number weekly_deaths date       excess_2020
  <chr> <chr>                  <int> <chr>                 <dbl>         <dbl> <date>           <dbl>
1 AUT   Austria              8840521 107.1279668605~           1             0 2020-01-06        1610
2 AUT   Austria              8840521 107.1279668605~           2             0 2020-01-13        1610
3 AUT   Austria              8840521 107.1279668605~           3             0 2020-01-20        1610

  

dput() для вышеуказанного:

 dput(x_worldwide_weekly_death_values[371:373,])
structure(list(ISO3 = c("AUT", "AUT", "AUT"), administrative_area_level_1 = c("Austria", 
"Austria", "Austria"), population = c(8840521L, 8840521L, 8840521L
), pop_density_km2 = c("107.127966860564", "107.127966860564", 
"107.127966860564"), week_number = c(1, 2, 3), weekly_deaths = c(0, 
0, 0), date = structure(c(18267, 18274, 18281), class = "Date"), 
    excess_2020 = c(1610, 1610, 1610)), row.names = c(NA, -3L
), class = c("tbl_df", "tbl", "data.frame"))
  

Ожидаемым результатом для столбца excess_2020 будут значения столбца DTotal, связанные с номером недели; Неделя 1 = 1610, неделя 2 = 1702, неделя 3 = 1797

   ISO3   Year  Week Sex   D0_14 D15_64 D65_74 D75_84  D85p DTotal   R0_14  R15_64 R65_74 R75_84  R85p
  <chr> <dbl> <dbl> <chr> <dbl>  <dbl>  <dbl>  <dbl> <dbl>  <dbl>   <dbl>   <dbl>  <dbl>  <dbl> <dbl>
1 AUT    2020     1 b         1    220    221    481   687   1610 4.07e-5 0.00196 0.0134 0.0399 0.157
2 AUT    2020     2 b         8    231    261    490   712   1702 3.26e-4 0.00206 0.0158 0.0407 0.163
3 AUT    2020     3 b        12    223    272    537   753   1797 4.89e-4 0.00198 0.0165 0.0446 0.173

  

dput() для вышеуказанного

 dput(excess_death_2020[1:3,])
structure(list(ISO3 = c("AUT", "AUT", "AUT"), Year = c(2020, 
2020, 2020), Week = c(1, 2, 3), Sex = c("b", "b", "b"), D0_14 = c(1, 
8, 12), D15_64 = c(220, 231, 223), D65_74 = c(221, 261, 272), 
    D75_84 = c(481, 490, 537), D85p = c(687, 712, 753), DTotal = c(1610, 
    1702, 1797), R0_14 = c(4.07296256273503e-05, 0.000325837005018803, 
    0.000488755507528204), R15_64 = c(0.00195783568851069, 0.00205572747293622, 
    0.00198453344789947), R65_74 = c(0.0133964529296798, 0.0158211502925177, 
    0.0164879420672982), R75_84 = c(0.0399495248686277, 0.0406970211759409, 
    0.044600613003021), R85p = c(0.157436284517545, 0.163165406952681, 
    0.172561167746305), RTotal = c(0.00948052042945739, 0.0100222644539978, 
    0.0105816740445559), Split = c(0, 0, 0), SplitSex = c(0, 
    0, 0), Forecast = c(1, 1, 1), date = structure(c(18267, 18274, 
    18281), class = "Date")), row.names = c(NA, -3L), class = c("tbl_df", 
"tbl", "data.frame"))

  

Я попробовал несколько вариантов ниже с небольшим успехом

 x_worldwide_weekly_deaths["excess_2020"] <- excess_death_2020$DTotal[excess_death_2020$Week[match(x_worldwide_weekly_death_values$week_number
                                         [x_worldwide_weekly_death_values$ISO3],
                                         excess_death_2020$Week[excess_death_2020$CountryCode])]]

  

Должен ли я не использовать match () по нескольким критериям или я неправильно его форматирую?

Очень признателен за любую помощь и предложения!

Комментарии:

1. Пожалуйста, предоставьте dput() выходные данные для каждого из примеров наборов данных, которыми вы делитесь. Кроме того, опубликуйте ожидаемый результат — это поможет проверить решения.

2. Да, пожалуйста, поделитесь своими данными, но также, хотя это возможно match , это, скорее всего, больше подходит для merge ознакомления ?merge с тем, как его использовать

3. взгляните на dplyr::left_join()

Ответ №1:

dplyr действительно ли это хорошо / легко для такого рода вещей. Вот упрощенный пример, который достигает обеих ваших целей (добавление NA для стран, которых нет в данных об избыточной смертности, и добавление NA для недель, которых нет в данных об избыточной смертности)…

 library(dplyr)

x_worldwide_weekly_death_values <-
  tribble(
    ~iso3c, ~week, ~covid_deaths,
    "AFG",      1,            0,
    "AFG",      2,           10,
    "AFG",      3,           30,
    "AFG",      4,           50,
    "AUT",      1,          120,
    "AUT",      2,          200,
    "AUT",      3,          320,
    "AUT",      4,          465,
    "XXX",      1,           10,
    "XXX",      2,           20,
    "XXX",      3,           30,
    "XXX",      4,           40,
  )

excess_death_2020 <- 
  tribble(
    ~iso3c, ~week, ~DTotal,
    "AFG",      1,       0,
    "AFG",      2,       0,
    "AFG",      3,       0,
    "AUT",      1,       1610,
    "AUT",      2,       1702,
    "AUT",      3,       1797,
    
  )

x_worldwide_weekly_death_values %>% 
  left_join(excess_death_2020, by = c("iso3c", "week"))
#> # A tibble: 12 x 4
#>    iso3c  week covid_deaths DTotal
#>    <chr> <dbl>        <dbl>  <dbl>
#>  1 AFG       1            0      0
#>  2 AFG       2           10      0
#>  3 AFG       3           30      0
#>  4 AFG       4           50     NA
#>  5 AUT       1          120   1610
#>  6 AUT       2          200   1702
#>  7 AUT       3          320   1797
#>  8 AUT       4          465     NA
#>  9 XXX       1           10     NA
#> 10 XXX       2           20     NA
#> 11 XXX       3           30     NA
#> 12 XXX       4           40     NA
  

Комментарии:

1. Спасибо CJ! Удалось отсортировать его с помощью left_join после комментария Ричарда, потрошенный, я так долго пытался заставить match() делать то, что я хочу! Но спасибо за ваш ответ, который намного более понятен, чем я мог бы добавить!