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

如何有效地删除(或添加)R中IP地址的前导零?,r,ip,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中删除前导零

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) 
要转到另一个方向,我们可以使用
printPadded
函数中拆分的值上的
gsub
删除前导零。就我个人而言,我建议不要删除前导零。无需删除零(或填充零),但固定宽度格式更易于读取和排序(即,对于那些字典式排序函数)



更新1:只是一个速度建议:如果你正在处理大量的IP地址,并且真的想加快速度,你可以考虑多核方法,比如
mclappy
plyr
包也很有用,其中包括
ddply()
。它们还通过
支持并行后端。parallel=TRUE
。不过,即使在单个核心上,几百万个IP地址也不会占用很长时间。

另一种方法是:

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

比sprintf需要的很多部门都好。

哇,感谢您的快速响应。我在strsplit(x,“\\”,perl=TRUE)中得到一个错误:非字符参数我是否需要以.character运行,因为它们当前是因子级别?我成功地运行了lappy(as.character(data$IP),printPadded)。谢谢在接受答案前等待几个小时。@Benjamin啊,你们应该小心考虑各种因素。它们可能会把一切都弄糟,因为有时它们看起来像字符向量,但最终可能会被视为整数。如果加载数据,例如作为
read.csv()
,请查找选项
stringsAsFactors=FALSE
。或者,您可以在选项中设置此选项-查看
?选项
。FWIW,我从未从将字符串作为因子加载中获益——我只在需要时进行显式因子转换(例如,在某些类型的模型中)
> 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"
my @ipparts = split(/\./, $ip);
for my $ii (0..$#ipparts)
{
    $ipparts[$ii] = $ipparts[$ii]+0;
}
$ip = join(".", @ipparts);