R-ohjelmointi.org

Tilastotieteellistä ohjelmointia R-kielellä

IP-osoitteiden järjestäminen

R-help-sivuilla oli mielenkiintoinen keskustelu pari päivää sitten ip-osoitteiden järjestämisestä oikeaan järjestykseen. Tavallisesti ohjelmat järjestävät ip-osoitteet ensimmäisen numeron mukaan suuruusjärjestykseen, jolloin järjestys menee väärin. Tässä keskustelusta hieman muokattu esimerkki ip-osoitteiden järjestämisestä R:llä (ja Perlillä):

> #Muodostetaan data.frame
> set.seed(10)
> n <- 4
> DF <- data.frame(
+   a = rnorm(n),
+   b = rnorm(n),
+   c = rnorm(n),
+   ip = replicate(n, paste(sample(255, 4), collapse='.'), simplify=TRUE)
+ )
> DF
            a          b          c              ip
1  0.01874617  0.2945451 -1.6266727  104.180.213.61
2 -0.18425254  0.3897943 -0.2564784   197.91.136.24
3 -1.37133055 -1.2080762  1.1017795  44.229.107.189
4 -0.59916772 -0.3636760  0.7557815 210.243.174.127
> 
> #Voidaan koittaa tuottaako normaali järjestäminen halutun tuloksen -> ei
> DF[order(DF$ip),]
            a          b          c              ip
1  0.01874617  0.2945451 -1.6266727  104.180.213.61
2 -0.18425254  0.3897943 -0.2564784   197.91.136.24
4 -0.59916772 -0.3636760  0.7557815 210.243.174.127
3 -1.37133055 -1.2080762  1.1017795  44.229.107.189
> 
> #Tehdään järjestys toisella tavalla (Peter Dalgaard)
> con <- textConnection(as.character(DF$ip))
> o <- do.call(order, read.table(con, sep="."))
> close(con)
> DF[o,]
            a          b          c              ip
3 -1.37133055 -1.2080762  1.1017795  44.229.107.189
1  0.01874617  0.2945451 -1.6266727  104.180.213.61
2 -0.18425254  0.3897943 -0.2564784   197.91.136.24
4 -0.59916772 -0.3636760  0.7557815 210.243.174.127
> 
> #Toinen, nopeampi tapa on tällainen (Henrik Bengtsson)
> ipsort <- function(DF, ipcol) {
+       ip <- strsplit(as.character(ipcol), split=".", fixed=TRUE)
+       ip <- unlist(ip, use.names=FALSE)
+       ip <- as.integer(ip);
+       dim(ip) <- c(4, nrow(DF))
+       o <- sort.list(ip[4,], method="radix", na.last=TRUE)
+       for (kk in 3:1) {
+         o <- o[sort.list(ip[kk,o], method="radix", na.last=TRUE)]
+         }
+       DF[o, ]
+       }
> 
> ipsort(DF, DF$ip)
            a          b          c              ip
3 -1.37133055 -1.2080762  1.1017795  44.229.107.189
1  0.01874617  0.2945451 -1.6266727  104.180.213.61
2 -0.18425254  0.3897943 -0.2564784   197.91.136.24
4 -0.59916772 -0.3636760  0.7557815 210.243.174.127
>

Tässä vielä yksinkertainen esimerkki, miten ip-osoitteet voi järjestää Perlillä:

#!/perl/bin/
 
use strict;
use warnings;
use Sort::Key::IPv4 qw(ipv4sort);
 
my @data = qw(104.180.213.61 197.91.136.24 44.229.107.189 210.243.174.127);
my @sorted = ipv4sort @data;
 
foreach my $ip (@sorted) {
    print "$ip\n";
 
}
 
Tulos:
44.229.107.189
104.180.213.61
197.91.136.24
210.243.174.127


Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *