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

时间:2011-11-17 22:00:04

标签: r ip

R中的两个数据帧都包含IP地址字段。在每个数据帧中,这些字段是“因子”。用户打算基于这些IP地址以及一些其他字段合并两个数据帧。问题是每个数据帧都有不同的IP格式:

Dataframe A examples: 123.456.789.123, 123.012.001.123, 987.001.010.100

Dataframe B中的相同IP格式为:

Dataframe B examples: 123.456.789.123, 123.12.1.123, 987.1.10.100

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

2 个答案:

答案 0 :(得分:6)

您可以使用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"

要向另一个方向前进,我们可以使用gsub函数中的分割值printPadded删除前导零。对于我的钱,我建议不要删除前导零。没有必要删除零(或填充它们),但固定宽度格式更容易阅读和排序(即对于那些排序函数的词典)。


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

答案 1 :(得分:2)

另一种方式是这样的:

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

比sprintf需要的很多分歧更好。