Как реализовать сложный оператор For-Loop + If - PullRequest
0 голосов
/ 20 сентября 2019

У меня есть два набора данных, каждый из которых содержит пятизначные ZIP-файлы.

Один набор данных выглядит следующим образом:

From    To      Territory

7501    10000   Unassigned
10001   10463   Agent 1
10464   10464   Unassigned
10465   11769   Agent 2

И второй набор данных выглядит следующим образом:

    zip5    address
1   10009   424 E 9TH ST APT 12, NEW YORK
2   10010   15 E 26TH ST APT 10C, NEW YORK
3   10013   310 GREENWICH ST, NEW YORK
4   10019   457 W 57TH ST, NEW YORK

Я хотел бы написать цикл forв R, который проходит по столбцу zip5 во втором наборе данных, затем проходит по столбцам From и To из набора данных 1, проверяя, попадает ли zip5 в From и Torange, и как только он находит совпадение, присваивает значение Territory из первого набора данных в новый столбец во втором наборе данных.

Я начал пытаться продумать логику, но быстро потерял сознание и подумал, чтообратитесь к сообществу StackOverflow за советом.

Вот моя первая попытка:

for (i in nrow(df1)){
  for(j in nrow(df2)){
    if(df1[1, "zip5"] > df2[1, "From"] & df1[1, "zip5"] <= df2[1, "To"])
      df1$newColumn = df2[j, "Territory"]
  }
}

1 Ответ

1 голос
/ 20 сентября 2019

Вы можете использовать data.table::foverlaps для этого:

library(data.table)

dat1 <- fread(text = '
From    To      Territory
7501    10000   Unassigned
10001   10463   "Agent 1"
10464   10464   Unassigned
10465   11769   "Agent 2"')

dat2 <- fread(text = '
zip5    address
10009   "424 E 9TH ST APT 12, NEW YORK"
10010   "15 E 26TH ST APT 10C, NEW YORK"
10013   "310 GREENWICH ST, NEW YORK"
10019   "457 W 57TH ST, NEW YORK"')

# if you use your own data and it is not a data.table, then do this:
setDT(dat1)
setDT(dat2)

Требования к использованию foverlap:

  1. Оба кадра должны иметьдва поля, «от» и «до».Хотя это может показаться бессмысленным, поскольку мы хотим определить, находится ли «zip5» в пределах «От» до «До», предпосылка функции состоит в том, чтобы найти перекрытия в двух диапазонах.Вместо того, чтобы вводить код специального случая, чтобы разрешить один столбец в одном кадре, они выбрали (я делаю вывод), чтобы сделать его общим.Это означает, что нам нужно скопировать zip5 в другой столбец.

  2. Обе таблицы должны иметь свои диапазоны в качестве «ключей».Если есть другие столбцы, которые являются ключами, то столбцы диапазона должны быть последними двумя.(И по порядку.)

# req't 1, need a range in the second frame
dat2[, zip5copy := zip5 ]
# set keys for both
setkey(dat1, From, To)
setkey(dat2, zip5, zip5copy)

И код:

foverlaps(dat1, dat2)
#     zip5                        address zip5copy  From    To  Territory
# 1:    NA                           <NA>       NA  7501 10000 Unassigned
# 2: 10009  424 E 9TH ST APT 12, NEW YORK    10009 10001 10463    Agent 1
# 3: 10010 15 E 26TH ST APT 10C, NEW YORK    10010 10001 10463    Agent 1
# 4: 10013     310 GREENWICH ST, NEW YORK    10013 10001 10463    Agent 1
# 5: 10019        457 W 57TH ST, NEW YORK    10019 10001 10463    Agent 1
# 6:    NA                           <NA>       NA 10464 10464 Unassigned
# 7:    NA                           <NA>       NA 10465 11769    Agent 2

Режим по умолчанию при отсутствии совпадений - nomatch=NA, что означает, чтопропущенные столбцы дополнительных строк заполняются NA, как указано выше.Это эквивалентно «полному объединению» (одна ссылка для объединений: https://stackoverflow.com/a/6188334). Если вы хотите просто сопоставить строки, то foverlaps(..., nomatch=NULL) даст вам только 4 строки. (Вы также можете изменить порядок dat1).и dat2, но вам, возможно, все равно придется использовать это, если вам нужны ваши фактические данные.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...