在基于ip范围的R基础上排序IP地址

时间:2016-10-11 17:45:43

标签: r loops sorting

我目前正忙着将特定的ip地址整理到A-B的ip范围。

例如。

       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
.
.

依次为col A和B中的X行数直到达到网络地址的末尾(大约1mil行〜)

Col A和B实际上是ip起始范围和ip结束范围,而我的目的是将其排序,例如,Col C 10.0.0.233应该属于第1行而不是第3行。

有什么方法可以对col C中的所有不同ip地址进行排序,使其属于col A和B的行?

谢谢:)

编辑:我正在使用数据表,如果它可能很重要。干杯。 编辑2:我需要在第2行进行此操作col c将适合行605而行605 Col C将进入第2行等等。

2 个答案:

答案 0 :(得分:1)

以下尝试使用滚动右连接,即它尝试在Col_C中找到匹配的IP范围[Col_A, Col_B]中的所有值。不会删除Col_C值,但会删除Col_C中没有匹配值的IP范围。

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

答案 1 :(得分:0)

我不知道这是否是您正在寻找的功能,但想法是将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>
相关问题