Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
查找使用for循环移动的总距离_R - Fatal编程技术网

查找使用for循环移动的总距离

查找使用for循环移动的总距离,r,R,我试图找出工人移动的总距离,我的df看起来像 Name x y John 12 34 John 15 31 John 8 38 John 20 14 我尝试使用dist(rbind())函数,但给出的结果不正确。它只是给出了sqrt((第1行)^2+(第2行)^2+(第3行)^2+(第4行)^2)的结果,我认为这是不正确的 所以我试着使用for循环来实现这一点,这样第1行和第2行、第2行和第3行之间的距离就可以分别计算出来,以后再求和。我该怎么

我试图找出工人移动的总距离,我的
df
看起来像

Name    x    y 
John    12  34
John    15  31
John    8   38
John    20  14 
我尝试使用
dist(rbind())
函数,但给出的结果不正确。它只是给出了
sqrt((第1行)^2+(第2行)^2+(第3行)^2+(第4行)^2)
的结果,我认为这是不正确的

所以我试着使用
for
循环来实现这一点,这样第1行和第2行、第2行和第3行之间的距离就可以分别计算出来,以后再求和。我该怎么做

我的代码当前看起来像:

for(i in nrow(df)){
  n <- dist(rbind(df$x,df$y))
}
我可以在以后通过跑步来总结:

sum(n)
对吗?

不需要循环

dplyr dplyr/tidyverse方法也可以覆盖多个名称(因为“名称”列的存在表示多个工作者)

df%
#按名称分组(以防DF中有多个工作人员)
#如果只有一个工人,则可以删除此行
分组单位(名称)%>%
#获取上一个x和y值
突变(x_prev=lag(x),y_prev=lag(y))%>%
#过滤掉没有上一个x值的行
过滤器(!is.na(x_prev))%>%
#计算距离
变异(距离=sqrt(绝对值(x-x\U上一个)^2+绝对值(y-y\U上一个)^2))%>%
#汇总以获得总距离
总结(总距离=总和(距离))
##A tible:1 x 2
#名称总距离
#               
#约翰一世41.0
基尔
#创建x和y矩阵,计算距离并根据结果创建矩阵
M
df
#名称x y
#1约翰12 34
#2约翰15 31
#3约翰8 38
#约翰20 14

n使用base R,您可以在每对连续的行上调用
dist
,然后调用
cumsum
相邻距离,以按名称获得结果

df <- read.table(text="Name    x    y 
John    12  34
John    15  31
John    8   38
John    20  14
Mark    11  13
Mark    16  18", header=TRUE)

by(df, df$Name, function(mat) {
    idx <- seq_len(nrow(mat))
    cumsum(mapply(function(i,j) dist(mat[c(i,j), c("x","y")]), 
        head(idx, -1), tail(idx, -1)))
})

df请分享您的预期输出@ChirayuChamoli补充了我的预期结果。感谢您的反馈。您没有在循环中的任何位置使用
i
。可能,您正在尝试执行,
n[i]您正在执行什么距离计算?@Wimpel-Euclidean distance。我应该早点提的对不起。所以我可以使用sqrt((x[1]-x[2])^2+(y[1]-y[2])^2)这类公式,但我不知道如何进行循环。有什么帮助吗?是的,有多个worker,但是我已经为每个worker创建了一个子集,这样每个worker都有自己的数据框。所以我想我可以从mutate()部分开始?也知道没有任何NA值,我还需要使用过滤代码吗?感谢您的回复和以后的回复。@Robo NA筛选是因为您无法计算第一行的距离,因为行驶的距离基于当前和以前的x和y值。对于
n
行,您将始终获得
n-1
计算的抖动。尝试注释代码中的行,以查看直到该点的结果。在这个解决方案中,您不必为每个工人创建单独的子集;您可以使用组合的df和每个工作人员的组。@Robo添加了一个基本解决方案。您刚才建议的大多数功能我从未见过。谢谢你的新信息!我将尝试一下这个代码说没有叫做“I”的对象。我做错了什么?另外,R如何知道是否使用了x或y列?请你解释一下代码好吗?我对编码&R相当陌生。事实上,当我按照您的代码制作数据帧时,它确实给了我相同的结果。之前,我只是使用了另一个给定的数据集。那么,如果我要使用一个已有8000多行的数据集,我该如何模拟它呢?我不能同时为x和y写c(8000个数字)。如果我使用已经生成的数据集,它会给我一个与上面相同的错误。我在这里提到(-1)时删除了第一列的名称:
df[I,-1],df[(I+1),-1]
。同样,您可以删除任何额外的列,只保留x和y列。
df <- data.frame( Name = c("John","John","John","John"),
                  x = c(12,15,8,20),
                  y = c(34,31,38,14),
                  stringsAsFactors = FALSE )

library(tidyverse)
df %>% 
  #group by name (just in case there are multiple workers in the DF)
  #you can remove this line if there is only 1 worker
  group_by( Name ) %>%
  #get the previous x and y value
  mutate( x_prev = lag( x ), y_prev = lag( y ) ) %>%
  #filter out rows without previous x value
  filter( !is.na( x_prev ) ) %>%
  #calculate the distance
  mutate( distance = sqrt( abs (x - x_prev )^2 + abs( y - y_prev )^2 ) ) %>%
  #summarise to get the total distance
  summarise( total_distance = sum( distance ) )

# # A tibble: 1 x 2
#     Name  total_distance
#     <chr>          <dbl>
#   1 John            41.0
#create a matrix of x and y, calculate the distance and create a matrix from the results
M <- as.matrix( dist( matrix( c( df$x, df$y ), ncol = 2 ) ) )
M
#           1         2         3        4
# 1  0.000000  4.242641  5.656854 21.54066
# 2  4.242641  0.000000  9.899495 17.72005
# 3  5.656854  9.899495  0.000000 26.83282
# 4 21.540659 17.720045 26.832816  0.00000
#get the first off diagonal of the matrix (row = column+1)
M[row(M) == col(M) + 1]
#[1]  4.242641  9.899495 26.832816
#sum the first off diagonal
sum( M[row(M) == col(M) + 1] )
#[1] 40.97495
df<-data.frame("Name" = rep(x = "John",times = 4),"x" = c(12,15,8,20),"y" = c(34,31,38,14))

#> df
#  Name  x  y
#1 John 12 34
#2 John 15 31
#3 John  8 38
#4 John 20 14

n<-numeric()
for(i in 1:(nrow(df) - 1)){
  n[i] <- dist(rbind(df[i,-1],df[(i + 1),-1]))
}
print(n)

#[1]  4.242641  9.899495 26.832816

sum(n)

#[1] 40.97495
df <- read.table(text="Name    x    y 
John    12  34
John    15  31
John    8   38
John    20  14
Mark    11  13
Mark    16  18", header=TRUE)

by(df, df$Name, function(mat) {
    idx <- seq_len(nrow(mat))
    cumsum(mapply(function(i,j) dist(mat[c(i,j), c("x","y")]), 
        head(idx, -1), tail(idx, -1)))
})
by(df, df$Name, function(mat) {
    idx <- seq_len(nrow(mat))
    cumsum(
        as.matrix(dist(mat[,c("x","y")]))[cbind(head(idx, -1), tail(idx, -1))])
})