Сортировка IP-адреса в базе R по диапазону ip

#r #loops #sorting

#r #циклы #сортировка

Вопрос:

В настоящее время я застрял в сортировке определенного IP-адреса по диапазону ip от A до B.

Например.

        Col A      Col B     Col C
1    10.0.0.0  10.0.0.255   1.5.2.1
2    10.0.1.0  10.0.3.255   60.5.1.30
3    10.0.4.0  10.0.4.255   10.0.0.233
.
.
.
605  60.5.1.0  60.5.1.255   10.0.2.254
.
.
  

и так далее и так для X-го количества строк в столбцах A и B, пока оно не достигнет конца сетевого адреса (около 1 миллиона строк ~)

Col A и B на самом деле являются начальным диапазоном ip и конечным диапазоном ip, в то время как я намереваюсь отсортировать его так, чтобы, например, Col C 10.0.0.233 должен принадлежать строке 1 вместо строки 3.

Есть ли какой-либо способ отсортировать все разные ip-адреса в col C таким образом, чтобы он принадлежал строке col A и B?

Спасибо 🙂

Редактировать: я использую таблицу данных, если это может иметь значение. Приветствия. Редактирование 2: мне нужно сделать так, чтобы в строке 2 col c помещался в строку 605, а строка 605 Col C вошла в строку 2 и т. Д.

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

1. Я смог воспроизвести вашу data.table, но для будущих вопросов, пожалуйста, используйте dput() описание тега R, чтобы упростить воспроизведение ваших данных. Приветствия.

2. Привет @Hack-R что вы подразумеваете под перепрограммированием таблицы данных?

3. Есть ли какие-либо совпадения в диапазонах IP [Col_A, Col_B] ? Что должно произойти, когда диапазон IP не Col_C подходит? Следует ли отбросить это значение?

4. Привет @ UweBlock нет, в диапазоне IP-адресов col a и B. Если нет диапазона IP, который соответствует col C, col C должен возвращать NA.

Ответ №1:

Следующая попытка использует скользящее правое соединение, то есть пытается найти все значения в Col_C соответствующем диапазоне IP [Col_A, Col_B] . Col_C Значение не отбрасывается, но диапазоны IP без соответствующего значения Col_C отбрасываются.

Пакет iptools используется для преобразования IP-адресов из удобочитаемого представления в числовое представление.

 library(data.table)
# Development version 1.9.7
ip <- fread( "id       Col_A      Col_B     Col_C
             1    10.0.0.0  10.0.0.255   1.5.2.1
             2    10.0.1.0  10.0.3.255   60.5.1.30
             3    10.0.4.0  10.0.4.255   10.0.0.233
             605  60.5.1.0  60.5.1.255   10.0.2.254
             ")

# convert strings to integers: an ip address actually is a 32 bit number
ip_cols <- paste0("Col_", LETTERS[1:3])
num_cols <- paste0("num_", LETTERS[1:3])
ip[, (num_cols) := lapply(.SD, iptools::ip_to_numeric), .SD = ip_cols]
# add column to join on (for clarity)
ip[, num_join := num_A]
# right join
result <- ip[ip[, .(Col_C, num_C)], on = .(num_join = num_C), roll = TRUE][order(id)]
# check upper bound - in case there are gaps in the IP ranges
result[num_join > num_B, c(ip_cols, num_cols) := NA][]

    id    Col_A      Col_B      Col_C      num_A      num_B      num_C   num_join    i.Col_C
1:   1 10.0.0.0 10.0.0.255    1.5.2.1  167772160  167772415   17105409  167772393 10.0.0.233
2:   2 10.0.1.0 10.0.3.255  60.5.1.30  167772416  167773183 1006960926  167772926 10.0.2.254
3: 605 60.5.1.0 60.5.1.255 10.0.2.254 1006960896 1006961151  167772926 1006960926  60.5.1.30
4:  NA       NA         NA         NA         NA         NA         NA   17105409    1.5.2.1
  

Ответ №2:

Я не знаю, является ли это той функциональностью, которую вы ищете, но идея заключается в сопоставлении ColA и ColC с теми, которые соответствуют числам перед 3-й точкой (.).

Если это так, я думаю, это может помочь

  df <- data.frame(ColA=c("10.0.0.0","10.0.1.0","10.0.4.0"),
             ColB=c("10.0.0.255","10.0.3.255","10.0.4.255"),
             ColC=c("1.5.2.1","60.5.1.30","10.0.0.233"))

require(dplyr)
DF1 <- df %>% select(1,2) %>% mutate(ColMatch=substr(start = 1,stop = as.numeric(regexpr(".([^.]*)$",df$ColA))-1,ColA))
DF2 <- df %>% select(3) %>% mutate(ColMatch=substr(start = 1,stop = as.numeric(regexpr(".([^.]*)$",df$ColC))-1,ColC)) 
DF <- left_join(DF1,DF2) %>% select(-ColMatch)
head(DF)

 ColA       ColB       ColC
1 10.0.0.0 10.0.0.255 10.0.0.233
2 10.0.1.0 10.0.3.255       <NA>
3 10.0.4.0 10.0.4.255       <NA>
  

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

1. Привет @Eduardo_Clark возможно ли ограничить его таким образом, чтобы он соответствовал каждому диапазону ip вместо 4-го октета? приветствия

2. Итак, я мало что знаю о диапазонах IP, так вы говорите мне, что ColA и ColB — это интервал? И вы хотите назначить ColC, который вписывается в этот интервал? Если да, то как работает диапазон, является ли 10.0.1.0 следующим IP-адресом после 10.0.0.255?

3. Да, @Eduardo_Clark 🙂