Выберите даты на основе значения другого столбца

#r #dataframe #for-loop

Вопрос:

У меня есть фрейм данных, содержащий идентификаторы участников ( 'Included.y' столбец). Для каждого участника мне нужно назначить дату встречи с одной из трех возможных дат ( 'date' столбец). В 'vis' столбце показан предпочтительный порядок даты назначения (V1, затем V2, затем V3). Однако, если значение в 'ficol' столбце равно или превышает 60, запись на прием на эту дату не может быть забронирована.

Так, например, участник 5 в приведенном ниже фрейме данных получит дату 2021-11-10, поскольку значение ficol не достигло 60. Тем не менее, участник 6 в идеале должен был бы получить дату 2021-10-05, но, поскольку уже есть 60 фиколов, это невозможно. На следующую дату, 2021-10-06, всего 20 фиколов, поэтому встречу можно запланировать там. Каждая встреча, запланированная на определенную дату, добавляет значение 2 в столбец ficol. Это означает, что если бы у нас было 2 дополнительных назначения на 2021-11-09 (что составляет 4 фикола), столбец фиколов достиг бы своего предела в 60 фиколов и, следовательно, не допускал бы больше назначений.

 # A tibble: 6 x 4
  Included.y vis   date       ficol
       <int> <chr> <date>     <chr>
1          5 V1    2021-11-10 NA   
2          5 V2    2021-11-11 NA   
3          5 V3    2021-11-09 56   
4          6 V1    2021-10-05 60   
5          6 V2    2021-10-06 20   
6          6 V3    2021-10-04 60  
 

Результатом для участников 5 и 6 будет:

 # A tibble: 2 x 4
  Included.y vis   date       ficol
       <dbl> <chr> <date>     <chr>
1          5 V1    2021-11-10 2    
2          6 V2    2021-10-06 22   
 

Пожалуйста, смотрите ниже вывод dput всего кадра данных.

 structure(list(Included.y = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 4L, 
4L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L, 7L, 8L, 8L), vis = c("V1", 
"V2", "V3", "V1", "V2", "V3", "V2", "V1", "V3", "V1", "V2", "V3", 
"V1", "V2", "V3", "V1", "V2", "V3", "V1", "V2"), date = structure(c(18892, 
18893, 18891, 18934, 18935, 18933, 18841, 18900, 18899, 18941, 
18942, 18940, 18905, 18906, 18904, 18912, 18913, 18911, 18919, 
18920), class = "Date"), ficol = c("36", NA, "60", NA, NA, "36", 
"60", NA, " 8", NA, NA, "56", "60", "20", "60", "56", NA, "60", 
"56", NA)), row.names = c(NA, -20L), class = c("tbl_df", "tbl", 
"data.frame"), na.action = structure(c(`7` = 7L, `9` = 9L, `11` = 11L, 
`29` = 29L, `33` = 33L, `35` = 35L, `39` = 39L, `43` = 43L, `45` = 45L, 
`48` = 48L, `50` = 50L, `52` = 52L, `54` = 54L, `61` = 61L, `63` = 63L, 
`70` = 70L, `72` = 72L, `75` = 75L, `80` = 80L, `86` = 86L, `94` = 94L, 
`96` = 96L, `102` = 102L, `109` = 109L, `111` = 111L, `114` = 114L, 
`117` = 117L, `120` = 120L, `121` = 121L, `123` = 123L, `126` = 126L, 
`128` = 128L, `136` = 136L, `138` = 138L, `145` = 145L, `147` = 147L, 
`159` = 159L, `170` = 170L, `173` = 173L, `176` = 176L, `178` = 178L, 
`180` = 180L, `182` = 182L, `188` = 188L, `193` = 193L, `195` = 195L, 
`199` = 199L, `201` = 201L, `207` = 207L, `217` = 217L, `219` = 219L, 
`227` = 227L, `231` = 231L, `233` = 233L, `235` = 235L, `237` = 237L, 
`240` = 240L, `245` = 245L, `251` = 251L, `262` = 262L, `264` = 264L, 
`267` = 267L, `280` = 280L, `282` = 282L, `283` = 283L, `285` = 285L, 
`287` = 287L, `291` = 291L, `293` = 293L, `297` = 297L, `298` = 298L, 
`300` = 300L, `301` = 301L, `303` = 303L, `309` = 309L, `311` = 311L, 
`314` = 314L, `317` = 317L, `323` = 323L, `327` = 327L, `333` = 333L, 
`342` = 342L, `345` = 345L, `354` = 354L, `362` = 362L, `364` = 364L, 
`366` = 366L, `367` = 367L, `369` = 369L, `375` = 375L, `376` = 376L, 
`378` = 378L, `380` = 380L, `388` = 388L, `390` = 390L, `393` = 393L, 
`403` = 403L, `405` = 405L, `413` = 413L, `420` = 420L, `435` = 435L, 
`437` = 437L, `443` = 443L, `448` = 448L, `450` = 450L, `458` = 458L, 
`464` = 464L, `466` = 466L, `468` = 468L, `469` = 469L, `471` = 471L, 
`472` = 472L, `474` = 474L, `475` = 475L, `477` = 477L, `482` = 482L, 
`485` = 485L, `489` = 489L, `490` = 490L, `492` = 492L, `494` = 494L, 
`497` = 497L, `522` = 522L, `523` = 523L, `525` = 525L, `528` = 528L, 
`532` = 532L, `534` = 534L, `537` = 537L, `540` = 540L, `543` = 543L, 
`547` = 547L, `549` = 549L, `554` = 554L, `567` = 567L, `574` = 574L, 
`576` = 576L, `579` = 579L, `584` = 584L, `589` = 589L, `591` = 591L, 
`593` = 593L, `596` = 596L, `598` = 598L, `600` = 600L, `603` = 603L, 
`604` = 604L, `606` = 606L, `608` = 608L, `618` = 618L, `634` = 634L, 
`636` = 636L, `639` = 639L, `640` = 640L, `642` = 642L, `646` = 646L, 
`648` = 648L, `650` = 650L, `660` = 660L, `666` = 666L, `669` = 669L, 
`675` = 675L, `678` = 678L, `681` = 681L, `683` = 683L, `693` = 693L, 
`695` = 695L, `700` = 700L, `702` = 702L, `708` = 708L, `714` = 714L, 
`716` = 716L, `718` = 718L, `720` = 720L, `723` = 723L, `725` = 725L, 
`727` = 727L, `729` = 729L, `731` = 731L, `752` = 752L, `754` = 754L, 
`756` = 756L, `759` = 759L, `774` = 774L, `779` = 779L, `782` = 782L, 
`784` = 784L, `786` = 786L, `793` = 793L, `795` = 795L, `803` = 803L, 
`806` = 806L, `808` = 808L, `810` = 810L, `812` = 812L, `820` = 820L, 
`822` = 822L, `828` = 828L, `829` = 829L, `831` = 831L, `833` = 833L, 
`835` = 835L, `837` = 837L, `841` = 841L, `843` = 843L, `845` = 845L, 
`848` = 848L, `852` = 852L, `853` = 853L, `855` = 855L, `860` = 860L, 
`863` = 863L, `865` = 865L, `867` = 867L, `873` = 873L, `874` = 874L, 
`876` = 876L, `879` = 879L, `882` = 882L, `885` = 885L, `889` = 889L, 
`891` = 891L, `893` = 893L, `906` = 906L, `907` = 907L, `909` = 909L, 
`913` = 913L, `915` = 915L, `918` = 918L, `919` = 919L, `921` = 921L, 
`924` = 924L, `926` = 926L, `928` = 928L, `930` = 930L, `934` = 934L, 
`936` = 936L, `941` = 941L, `960` = 960L, `961` = 961L, `963` = 963L, 
`965` = 965L, `983` = 983L, `986` = 986L, `988` = 988L, `990` = 990L, 
`1001` = 1001L, `1007` = 1007L, `1011` = 1011L, `1013` = 1013L, 
`1018` = 1018L, `1020` = 1020L, `1024` = 1024L, `1026` = 1026L, 
`1031` = 1031L, `1034` = 1034L, `1044` = 1044L, `1046` = 1046L, 
`1049` = 1049L, `1053` = 1053L, `1056` = 1056L, `1059` = 1059L, 
`1069` = 1069L, `1071` = 1071L, `1077` = 1077L, `1080` = 1080L, 
`1086` = 1086L, `1093` = 1093L, `1095` = 1095L, `1097` = 1097L, 
`1102` = 1102L, `1104` = 1104L, `1108` = 1108L, `1110` = 1110L, 
`1121` = 1121L, `1125` = 1125L, `1138` = 1138L, `1140` = 1140L, 
`1152` = 1152L, `1154` = 1154L, `1156` = 1156L, `1158` = 1158L, 
`1165` = 1165L, `1167` = 1167L, `1170` = 1170L, `1179` = 1179L, 
`1183` = 1183L, `1185` = 1185L, `1188` = 1188L, `1189` = 1189L, 
`1191` = 1191L, `1192` = 1192L, `1194` = 1194L, `1202` = 1202L, 
`1209` = 1209L, `1213` = 1213L, `1215` = 1215L, `1218` = 1218L, 
`1220` = 1220L, `1229` = 1229L, `1233` = 1233L, `1235` = 1235L, 
`1239` = 1239L, `1240` = 1240L, `1242` = 1242L, `1243` = 1243L, 
`1245` = 1245L, `1246` = 1246L, `1248` = 1248L, `1254` = 1254L, 
`1256` = 1256L, `1262` = 1262L, `1269` = 1269L, `1275` = 1275L, 
`1276` = 1276L, `1278` = 1278L, `1293` = 1293L, `1295` = 1295L, 
`1297` = 1297L, `1299` = 1299L, `1301` = 1301L, `1303` = 1303L, 
`1305` = 1305L, `1307` = 1307L, `1311` = 1311L, `1312` = 1312L, 
`1314` = 1314L, `1315` = 1315L, `1317` = 1317L, `1328` = 1328L, 
`1330` = 1330L, `1332` = 1332L, `1334` = 1334L, `1336` = 1336L, 
`1338` = 1338L, `1341` = 1341L, `1343` = 1343L, `1346` = 1346L, 
`1352` = 1352L, `1356` = 1356L, `1361` = 1361L, `1373` = 1373L, 
`1380` = 1380L, `1381` = 1381L, `1383` = 1383L, `1384` = 1384L, 
`1386` = 1386L, `1388` = 1388L, `1392` = 1392L, `1393` = 1393L, 
`1395` = 1395L, `1398` = 1398L, `1401` = 1401L, `1411` = 1411L, 
`1413` = 1413L, `1414` = 1414L, `1416` = 1416L, `1418` = 1418L, 
`1427` = 1427L, `1433` = 1433L, `1437` = 1437L, `1440` = 1440L, 
`1443` = 1443L, `1444` = 1444L, `1446` = 1446L, `1448` = 1448L, 
`1451` = 1451L, `1464` = 1464L, `1472` = 1472L, `1475` = 1475L, 
`1483` = 1483L, `1485` = 1485L, `1493` = 1493L, `1500` = 1500L, 
`1502` = 1502L, `1504` = 1504L, `1506` = 1506L, `1511` = 1511L, 
`1516` = 1516L, `1518` = 1518L, `1523` = 1523L, `1528` = 1528L, 
`1530` = 1530L, `1539` = 1539L, `1545` = 1545L, `1546` = 1546L, 
`1548` = 1548L, `1550` = 1550L, `1553` = 1553L, `1556` = 1556L, 
`1558` = 1558L, `1560` = 1560L, `1565` = 1565L, `1568` = 1568L, 
`1575` = 1575L, `1576` = 1576L, `1578` = 1578L, `1583` = 1583L, 
`1590` = 1590L, `1596` = 1596L, `1599` = 1599L, `1605` = 1605L, 
`1606` = 1606L, `1608` = 1608L, `1613` = 1613L, `1616` = 1616L, 
`1627` = 1627L, `1629` = 1629L, `1643` = 1643L, `1645` = 1645L, 
`1647` = 1647L, `1653` = 1653L, `1655` = 1655L, `1661` = 1661L, 
`1663` = 1663L, `1665` = 1665L, `1674` = 1674L, `1678` = 1678L, 
`1680` = 1680L, `1685` = 1685L, `1692` = 1692L, `1696` = 1696L, 
`1698` = 1698L, `1702` = 1702L, `1704` = 1704L, `1710` = 1710L, 
`1711` = 1711L, `1713` = 1713L, `1720` = 1720L, `1722` = 1722L, 
`1725` = 1725L, `1726` = 1726L, `1728` = 1728L, `1730` = 1730L, 
`1732` = 1732L, `1734` = 1734L, `1736` = 1736L, `1738` = 1738L, 
`1740` = 1740L, `1743` = 1743L, `1746` = 1746L, `1750` = 1750L, 
`1752` = 1752L, `1759` = 1759L, `1761` = 1761L, `1764` = 1764L, 
`1767` = 1767L, `1768` = 1768L, `1770` = 1770L, `1777` = 1777L, 
`1779` = 1779L, `1785` = 1785L, `1786` = 1786L, `1788` = 1788L, 
`1791` = 1791L, `1792` = 1792L, `1794` = 1794L, `1801` = 1801L, 
`1803` = 1803L, `1805` = 1805L, `1809` = 1809L, `1813` = 1813L, 
`1815` = 1815L, `1817` = 1817L, `1820` = 1820L, `1823` = 1823L, 
`1830` = 1830L, `1843` = 1843L, `1845` = 1845L, `1848` = 1848L, 
`1857` = 1857L, `1860` = 1860L, `1862` = 1862L, `1864` = 1864L, 
`1866` = 1866L, `1867` = 1867L, `1869` = 1869L, `1870` = 1870L, 
`1872` = 1872L, `1875` = 1875L, `1876` = 1876L, `1878` = 1878L, 
`1879` = 1879L, `1881` = 1881L, `1883` = 1883L, `1890` = 1890L, 
`1893` = 1893L, `1901` = 1901L, `1911` = 1911L, `1916` = 1916L, 
`1920` = 1920L, `1924` = 1924L, `1926` = 1926L, `1927` = 1927L, 
`1929` = 1929L, `1935` = 1935L, `1938` = 1938L, `1941` = 1941L, 
`1942` = 1942L, `1944` = 1944L, `1945` = 1945L, `1947` = 1947L, 
`1955` = 1955L, `1960` = 1960L, `1962` = 1962L, `1963` = 1963L, 
`1965` = 1965L, `1968` = 1968L, `1980` = 1980L, `1982` = 1982L, 
`1984` = 1984L, `1986` = 1986L, `1991` = 1991L, `2000` = 2000L, 
`2008` = 2008L, `2010` = 2010L, `2015` = 2015L, `2017` = 2017L, 
`2019` = 2019L, `2022` = 2022L, `2025` = 2025L, `2028` = 2028L, 
`2029` = 2029L, `2031` = 2031L, `2033` = 2033L, `2049` = 2049L, 
`2051` = 2051L, `2053` = 2053L, `2055` = 2055L, `2057` = 2057L, 
`2062` = 2062L, `2064` = 2064L, `2066` = 2066L, `2069` = 2069L, 
`2071` = 2071L, `2073` = 2073L, `2076` = 2076L, `2080` = 2080L, 
`2082` = 2082L, `2084` = 2084L, `2090` = 2090L, `2096` = 2096L, 
`2099` = 2099L, `2101` = 2101L, `2103` = 2103L, `2108` = 2108L, 
`2110` = 2110L, `2112` = 2112L, `2120` = 2120L, `2122` = 2122L, 
`2124` = 2124L, `2125` = 2125L, `2127` = 2127L, `2130` = 2130L, 
`2135` = 2135L, `2143` = 2143L, `2145` = 2145L, `2149` = 2149L, 
`2151` = 2151L, `2154` = 2154L, `2157` = 2157L, `2166` = 2166L, 
`2169` = 2169L, `2171` = 2171L, `2185` = 2185L, `2187` = 2187L, 
`2189` = 2189L, `2192` = 2192L, `2194` = 2194L, `2196` = 2196L, 
`2203` = 2203L, `2205` = 2205L, `2206` = 2206L, `2208` = 2208L, 
`2212` = 2212L, `2214` = 2214L, `2216` = 2216L, `2232` = 2232L, 
`2234` = 2234L, `2238` = 2238L, `2242` = 2242L, `2244` = 2244L, 
`2247` = 2247L, `2250` = 2250L, `2251` = 2251L, `2253` = 2253L, 
`2255` = 2255L, `2258` = 2258L, `2265` = 2265L, `2267` = 2267L, 
`2273` = 2273L, `2277` = 2277L, `2282` = 2282L, `2287` = 2287L, 
`2289` = 2289L, `2290` = 2290L, `2292` = 2292L, `2296` = 2296L, 
`2298` = 2298L, `2299` = 2299L, `2301` = 2301L, `2302` = 2302L, 
`2304` = 2304L, `2305` = 2305L, `2307` = 2307L, `2310` = 2310L, 
`2317` = 2317L, `2319` = 2319L, `2324` = 2324L, `2326` = 2326L, 
`2328` = 2328L, `2334` = 2334L, `2335` = 2335L, `2337` = 2337L, 
`2338` = 2338L, `2340` = 2340L, `2341` = 2341L, `2343` = 2343L, 
`2348` = 2348L, `2352` = 2352L, `2361` = 2361L, `2362` = 2362L, 
`2364` = 2364L, `2365` = 2365L, `2367` = 2367L, `2383` = 2383L, 
`2385` = 2385L, `2390` = 2390L, `2393` = 2393L, `2403` = 2403L, 
`2407` = 2407L, `2409` = 2409L, `2418` = 2418L, `2421` = 2421L, 
`2425` = 2425L, `2427` = 2427L, `2432` = 2432L, `2436` = 2436L, 
`2440` = 2440L, `2442` = 2442L, `2445` = 2445L, `2448` = 2448L, 
`2457` = 2457L, `2460` = 2460L, `2464` = 2464L, `2466` = 2466L, 
`2468` = 2468L, `2470` = 2470L, `2472` = 2472L, `2477` = 2477L, 
`2481` = 2481L, `2494` = 2494L, `2496` = 2496L, `2504` = 2504L, 
`2508` = 2508L, `2514` = 2514L, `2518` = 2518L, `2520` = 2520L, 
`2522` = 2522L, `2532` = 2532L, `2535` = 2535L, `2546` = 2546L, 
`2551` = 2551L, `2553` = 2553L, `2557` = 2557L, `2559` = 2559L, 
`2560` = 2560L, `2562` = 2562L, `2565` = 2565L, `2570` = 2570L, 
`2574` = 2574L, `2575` = 2575L, `2577` = 2577L, `2578` = 2578L, 
`2580` = 2580L, `2582` = 2582L, `2585` = 2585L), class = "omit"))
 

Как мы можем с этим справиться?

Заранее спасибо!

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

1. итак, в случае, когда у участника 3 есть только один слот и он заполнен, т. е. 3 V2 2021-08-02 60, они назначены на другую дату или они просто отброшены?

2. В случае, если доступны только даты, которые уже содержат значение ficol 60, участник будет удален. Спасибо, что спросили!

3. Вы что — нибудь пробовали?

Ответ №1:

Я придумал решение, используя данные.таблица ниже. Пожалуйста, дайте мне знать, если у вас возникнут какие-либо вопросы.

 library(data.table)
library(lubridate)

dt <- data.table(dt)
dt[, c("date", "ficol") := .(ymd(date), as.numeric(ficol))]

# Sort by ID and visit 
setorder(dt, Included.y, vis)

# Flag open appointment
dt[, open := ifelse(is.na(ficol) | ficol<60, TRUE, FALSE)]

# Select first open appointment and update ficol
out_dt <- dt[open==TRUE, .SD[1], by = c("Included.y")]
out_dt[, ficol := ifelse(is.na(ficol), 2, ficol 2)]
out_dt[, open := NULL]

out_dt

   Included.y vis       date ficol
1:          1  V1 2021-09-22    38
2:          2  V1 2021-11-03     2
3:          4  V1 2021-09-30     2
4:          5  V1 2021-11-10     2
5:          6  V2 2021-10-06    22
6:          7  V1 2021-10-12    58
7:          8  V1 2021-10-19    58
 

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

1. Привет, lil_barnacle, ваше решение выше будет хорошо работать, если даты не будут встречаться более одного раза. Однако реальный фрейм данных состоит примерно из 900 участников, поэтому даты будут встречаться более одного раза. Каждый раз, когда выбрана дата, ей нужно будет подсчитывать 2 во времени фикола для каждого выбора даты, теперь она добавляет 2 только один раз. В реальном наборе данных 11 людям будет назначена дата 2021-08-26, и фиколы начали в NA. Таким образом, количество фиколов после назначения дат 11 людям составило бы 22, а сейчас оно остается на уровне 2. Есть ли какой-нибудь способ объяснить это? Спасибо за помощь

2. Кроме того, дата, для начала которой уже было бы 58 фиколов, не должна включать в себя более 1 участника (с тех пор она достигает 60). В вашем решении накопленное количество фиколов не учитывается