如何有效地删除(或添加)在R中的IP地址前导零



R中的两个数据帧各自包含IP地址字段。在每个数据框中,这些字段是"因子"。用户打算基于这些IP地址和其他一些字段合并两个数据帧。问题是每个数据帧对于ip有不同的格式:

Dataframe A examples: 123.456.789.123, 123.012.001.123, 987.001.010.100

数据帧B中相同的ip将被格式化为:

Dataframe B examples: 123.456.789.123, 123.12.1.123, 987.1.10.100

最好(最有效)的方法是从A中删除前导零或将它们添加到B中,以便它们可以在合并中使用?该操作将在数百万条记录上执行,因此"最有效"是考虑到计算时间(需要相对快速)。

您可以使用sprintf来格式化部分。例如,对于给定的数值a,您可以执行以下操作:

b <- sprintf("%.3d", a) 

所以,对于IP地址,试试这个函数:

printPadded <- function(x){
  retStr = paste(sprintf("%.3d",unlist(lapply(strsplit(x,"\.", perl = TRUE), as.numeric))), collapse = ".")
  return(retStr)
}

下面是两个例子:

> printPadded("1.2.3.4")
[1] "001.002.003.004"
> lapply(c("1.2.3.4","5.67.100.9"), printPadded)
[[1]]
[1] "001.002.003.004"
[[2]]
[1] "005.067.100.009"

在另一个方向上,我们可以删除前导零,使用gsubprintPadded函数中的分裂值。就我个人而言,我建议不要去掉前面的零。没有必要删除零(或填充它们),但固定宽度格式更容易阅读和排序(即对于那些字典排序函数)。


更新1:只是一个速度建议:如果你正在处理很多IP地址,并且真的想加快速度,你可能会考虑多核方法,比如mclapplyplyr包也很有用,ddply()是其中一个选项。这些也支持并行后端,通过.parallel = TRUE。尽管如此,即使在单核上,数百万个IP地址也不会花费很长时间。

另一种方式是:

my @ipparts = split(/./, $ip);
for my $ii (0..$#ipparts)
{
    $ipparts[$ii] = $ipparts[$ii]+0;
}
$ip = join(".", @ipparts);

比sprintf需要的一大堆划分要好。

最新更新