簡體   English   中英

計算R中數據幀中每兩行之間的夾角(每行是一個向量)?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM