[英]Calculate difference between rows in R based on a specifc row for each group
[英]Calculate an angle between each 2 rows in a dataframe (each row is a vector) in R?
給定重力數據框:
df <- structure(list(user_id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L), obs_id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), scroll_id = c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), gra_x = c(-0.76694775, -0.7770001,
-0.7770001, -0.7770001, -0.7864253, -0.7864253, -0.7864253, -0.7864253,
-0.7947834, -0.80270606), gra_y = c(7.083949, 7.0901933, 7.0901933,
7.0901933, 7.096873, 7.096873, 7.096873, 7.096873, 7.1042953,
7.1121664), gra_z = c(6.737941, 6.730217, 6.730217, 6.730217,
6.722077, 6.722077, 6.722077, 6.722077, 6.713248, 6.7039647)), .Names = c("user_id",
"obs_id", "scroll_id", "gra_x", "gra_y", "gra_z"), row.names = c(NA,
-10L), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), vars = c("user_id",
"obs_id", "scroll_id"), drop = TRUE, indices = list(0:9), group_sizes = 10L, biggest_group_size = 10L, labels = structure(list(
user_id = 1L, obs_id = 1L, scroll_id = 1L), row.names = c(NA,
-1L), class = "data.frame", vars = c("user_id", "obs_id", "scroll_id"
), drop = TRUE, .Names = c("user_id", "obs_id", "scroll_id")))
我想計算每個2個向量之間的角度(gra_x, gra_y, gra_z)
使用:
angle <- function(x,y){
dot.prod <- x%*%y
norm.x <- norm(x,type="2")
norm.y <- norm(y,type="2")
theta <- acos(dot.prod / (norm.x * norm.y))
as.numeric(theta)
}
我嘗試使用:
df %>%
select(gra_x, gra_y, gra_z) %>%
mutate(theta = angle(c(gra_x, gra_y, gra_z), c(lead(gra_x), lead(gra_y), lead(gra_z))))
但是它返回一個錯誤。 請告知如何計算每兩行之間的角度?
我認為這樣做比較容易,而且效率可能更高(沒有dplyr
語法)。 請參閱[ R:逐行dplyr :: mutate使用函數,該函數接受數據幀行並返回整數和基准。
要考慮的另一件事是, acos
有時返回NaN
。 中提供了一個解決方案(請參閱[ acos(1)對於某些值,而不是其他值,返回NaN )並在下面的修改的angle()
函數中使用。
angle <- function(x,y){
dot.prod <- as.numeric(x%*%y )
norm.x <- norm(x,type="2")
norm.y <- norm(y,type="2")
atheta<-dot.prod / (norm.x * norm.y)
theta <- acos(pmin(pmax(atheta,-1.0),1.0))
as.numeric(theta)
}
我們可以使用for
循環簡單地計算每兩行之間的角度:
df<-as.matrix(df)
df<-cbind(df, theta=NA)
for (i in 1:(nrow(df)-1)){
df[i,"theta"]= angle(df[i,c("gra_x","gra_y","gra_z")] , df[i+1,c("gra_x","gra_y","gra_z")])
}
df
# user_id obs_id scroll_id gra_x gra_y gra_z theta
# [1,] 1 1 1 -0.7669478 7.083949 6.737941 0.001441019
# [2,] 1 1 1 -0.7770001 7.090193 6.730217 0.000000000
# [3,] 1 1 1 -0.7770001 7.090193 6.730217 0.000000000
# [4,] 1 1 1 -0.7770001 7.090193 6.730217 0.001441059
# [5,] 1 1 1 -0.7864253 7.096873 6.722077 0.000000000
# [6,] 1 1 1 -0.7864253 7.096873 6.722077 0.000000000
# [7,] 1 1 1 -0.7864253 7.096873 6.722077 0.000000000
# [8,] 1 1 1 -0.7864253 7.096873 6.722077 0.001452513
# [9,] 1 1 1 -0.7947834 7.104295 6.713248 0.001480881
#[10,] 1 1 1 -0.8027061 7.112166 6.703965 NA
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.