#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 🙂