【发布时间】:2014-06-30 21:01:12
【问题描述】:
我写了一个函数来比较 IP 地址的相似性,并让用户选择八位字节中的详细程度。例如,在地址255.255.255.0 和255.255.255.1 中,用户可以指定他们只想比较第一个、第一个和第二个、第一个、第二个、第三个等八位字节。
函数如下:
did.change.ip=function(vec, detail){
counter=2
result.vec=FALSE
r.list=strsplit(vec, '.', fixed=TRUE)
for(i in vec){
if(counter>length(vec)){
break
}
first=as.numeric(r.list[[counter-1]][1:detail])
second=as.numeric(r.list[[counter]][1:detail])
if(sum(first==second)==detail){
result.vec=append(result.vec,FALSE)
}
else{
result.vec=append(result.vec,TRUE)
}
counter=counter+1
}
return(result.vec)
}
一旦数据开始变大,它真的很慢。对于 500,000 行的数据集,system.time() 结果为:
user system elapsed
208.36 0.59 209.84
是否有任何 R 高级用户对如何更有效地编写此代码有所了解?我知道lapply() 是循环遍历向量/数据帧的首选方法,但我不知道如何为此目的访问向量中的前一个元素。我试图快速勾勒出一些东西,但它返回一个语法错误:
test=function(vec, detail){
rlist=strsplit(vec, '.', fixed=TRUE)
r.value=vapply(rlist, function(x,detail) ifelse(x[1:detail]==x[1:detail] TRUE, FALSE))
}
我在下面创建了一些用于测试目的的示例数据:
stack.data=structure(list(V1 = c("247.116.209.66", "195.121.47.105", "182.136.49.12",
"237.123.100.50", "120.30.174.18", "29.85.72.70", "18.186.76.177",
"33.248.142.26", "109.97.92.50", "217.138.155.145", "20.203.156.2",
"71.1.51.190", "31.225.208.60", "55.25.129.73", "211.204.249.244",
"198.137.15.53", "234.106.102.196", "244.3.87.9", "205.242.10.22",
"243.61.212.19", "32.165.79.86", "190.207.159.147", "157.153.136.100",
"36.151.152.15", "2.254.210.246", "3.42.1.208", "30.11.229.18",
"72.187.36.103", "98.114.189.34", "67.93.180.224")), .Names = "V1", class = "data.frame", row.names = c(NA,
-30L))
【问题讨论】:
标签: r for-loop vectorization