R语言:如何对数据框每行的4个参数列应用大圆距离公式?
没问题,用apply()函数完全能搞定这个需求,写法还挺直观的。我一步步给你演示:
首先先确认你的数据框创建代码(我帮你格式化了下,看起来更清晰):
d <- as.data.frame( split( as.data.frame( c(33.43527, -112.01194, 37.72139, -122.22111, -3.78444, -73.30833, -12.02667, -77.12278, 37.43555, 38.88333, 40.97667, 28.81528) * pi/180 ), 1:4 ) ) colnames(d) <- c('lat','lon','lat2','lon2')
接下来用apply()逐行处理数据框就行——apply()的MARGIN参数设为1就代表按行操作。我们写个匿名函数,把每行的四个经纬度值提出来,代入你的大圆距离公式:
# 计算每行的大圆距离(转换为英里) answer <- apply(d, 1, function(row) { # 从当前行提取经纬度 lat <- row["lat"] lon <- row["lon"] lat2 <- row["lat2"] lon2 <- row["lon2"] # 代入公式算出距离(这里sum可以省略,单个值求和不影响结果) acos(sin(lat) * sin(lat2) + cos(lat) * cos(lat2) * cos(lon2 - lon)) * 6371 * 0.62137 })
运行这段代码后,输出结果和你预期的完全一致:
> answer [1] 645.0978 626.3632 591.4725
额外说明:
apply(d, 1, FUN):MARGIN=1是按行应用函数,MARGIN=2是按列,这里我们需要逐行计算两点距离,所以用1。- 匿名函数里的
row就是数据框的当前行,用列名提取值的写法可读性更强,如果你想省事儿,也可以用索引(比如row[1]对应lat,row[3]对应lat2),代码会更短:answer <- apply(d, 1, function(row) { acos(sin(row[1]) * sin(row[3]) + cos(row[1]) * cos(row[3]) * cos(row[4] - row[2])) * 6371 * 0.62137 })
两种写法都能得到正确结果,看你偏好哪种风格~
内容的提问来源于stack exchange,提问作者Tracy
相关产品推荐
相关产品推荐

