R:按行对循环 data.frame
R: Loop through data.frame in row-pairs
我想成对处理一些 GPS 数据行。
目前,我是在普通的 for 循环中执行此操作,但我确信有更好更快的方法。
n = 100
testdata <- as.data.frame(cbind(runif(n,1,10), runif(n,0,360), runif(n,14,16), runif(n, 46,49)))
colnames(testdata) <- c("speed", "heading", "long", "lat")
head(testdata)
diffmatrix <- as.data.frame(matrix(ncol = 3, nrow = dim(testdata)[1] - 1))
colnames(diffmatrix) <- c("distance","heading_diff","speed_diff")
for (i in 1:(dim(testdata)[1] - 1)) {
diffmatrix[i,1] <- spDists(as.matrix(testdata[i:(i+1),c('long','lat')]),
longlat = T, segments = T)*1000
diffmatrix[i,2] <- testdata[i+1,]$heading - testdata[i,]$heading
diffmatrix[i,3] <- testdata[i+1,]$speed - testdata[i,]$speed
}
head(diffmatrix)
我如何使用应用函数来做到这一点?
或者是否可以并行计算?
非常感谢!
我不确定你想用结束条件做什么,但使用 dplyr
你可以在不使用 for 循环的情况下完成所有这些。
library(dplyr)
testdata %>% mutate(heading_diff = c(diff(heading),0),
speed_diff = c(diff(speed),0),
longdiff = c(diff(long),0),
latdiff = c(diff(lat),0))
%>% rowwise()
%>% mutate(spdist = spDists(cbind(c(long,long + longdiff),c(lat,lat +latdiff)),longlat = T, segments = T)*1000 )
%>% select(heading_diff,speed_diff,distance = spdist)
# heading_diff speed_diff distance
# <dbl> <dbl> <dbl>
# 1 15.9 0.107 326496
# 2 -345 -4.64 55184
# 3 124 -1.16 25256
# 4 85.6 5.24 221885
# 5 53.1 -2.23 17599
# 6 -184 2.33 225746
我将在下面解释每个部分:
管道运算符%>%
本质上是一个链,它将一个操作的结果发送到下一个操作。所以我们从您的测试数据开始并将其发送到 mutate 函数。
使用mutate
创建 4 个新列,它们是从一行到下一行的差异测量值。在最后一行添加 0,因为在最后一个数据点之后没有测量。 (可以做类似 NA 的事情)
接下来,一旦您有了想要使用 rowwise
的差异,您就可以将 spDists
函数应用于每一行。
最后我们使用 mutate
创建另一个列,它调用我们之前创建的原始 4 列。
为了仅获取您关注的 3 列,我在末尾使用了 select
语句。如果你想要整个数据框,你可以省略它。
我想成对处理一些 GPS 数据行。
目前,我是在普通的 for 循环中执行此操作,但我确信有更好更快的方法。
n = 100
testdata <- as.data.frame(cbind(runif(n,1,10), runif(n,0,360), runif(n,14,16), runif(n, 46,49)))
colnames(testdata) <- c("speed", "heading", "long", "lat")
head(testdata)
diffmatrix <- as.data.frame(matrix(ncol = 3, nrow = dim(testdata)[1] - 1))
colnames(diffmatrix) <- c("distance","heading_diff","speed_diff")
for (i in 1:(dim(testdata)[1] - 1)) {
diffmatrix[i,1] <- spDists(as.matrix(testdata[i:(i+1),c('long','lat')]),
longlat = T, segments = T)*1000
diffmatrix[i,2] <- testdata[i+1,]$heading - testdata[i,]$heading
diffmatrix[i,3] <- testdata[i+1,]$speed - testdata[i,]$speed
}
head(diffmatrix)
我如何使用应用函数来做到这一点?
或者是否可以并行计算?
非常感谢!
我不确定你想用结束条件做什么,但使用 dplyr
你可以在不使用 for 循环的情况下完成所有这些。
library(dplyr)
testdata %>% mutate(heading_diff = c(diff(heading),0),
speed_diff = c(diff(speed),0),
longdiff = c(diff(long),0),
latdiff = c(diff(lat),0))
%>% rowwise()
%>% mutate(spdist = spDists(cbind(c(long,long + longdiff),c(lat,lat +latdiff)),longlat = T, segments = T)*1000 )
%>% select(heading_diff,speed_diff,distance = spdist)
# heading_diff speed_diff distance
# <dbl> <dbl> <dbl>
# 1 15.9 0.107 326496
# 2 -345 -4.64 55184
# 3 124 -1.16 25256
# 4 85.6 5.24 221885
# 5 53.1 -2.23 17599
# 6 -184 2.33 225746
我将在下面解释每个部分:
管道运算符%>%
本质上是一个链,它将一个操作的结果发送到下一个操作。所以我们从您的测试数据开始并将其发送到 mutate 函数。
使用mutate
创建 4 个新列,它们是从一行到下一行的差异测量值。在最后一行添加 0,因为在最后一个数据点之后没有测量。 (可以做类似 NA 的事情)
接下来,一旦您有了想要使用 rowwise
的差异,您就可以将 spDists
函数应用于每一行。
最后我们使用 mutate
创建另一个列,它调用我们之前创建的原始 4 列。
为了仅获取您关注的 3 列,我在末尾使用了 select
语句。如果你想要整个数据框,你可以省略它。