使用 R 重新分配定向(圆形)数据中的位置

Reassigning positions in directional (circular) data using R

我将桶排列成圆形(标记为 pos 1 - 6)。一只猴子站在中心,在三个独立试验 (sets) 中随机向每个桶 (inf) 扔石头。

这里的目标是首先确定特定组中投掷到桶中的石子数量最多。一旦确定,具有最高石头的桶将被分配到新位置(expected_pos)“1”。然后我需要比较它左边和右边的桶,以确定哪个桶的石头数量第二多。该桶被分配到位置“2”。这决定了为其余桶分配新位置的方向。我能够了解它的两个方面——从 inf 和第二高的位置 pos2 中找到最大值。我真的需要最后一部分的帮助,即为其余的桶分配新位置。在这个虚拟数据集中,我插入了一列 'expected_pos' 来表示预期结果。

#Dataset
set <- c(1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3)
pos <- c(1,2,3,4,5,6,1,2,3,4,5,6,1,2,3,4,5,6)
inf <- c(1000,200,3,4,5,6,1,2,3,4,500,6000,1,2,300,4000,5,6)
expected_pos <- c(1,2,3,4,5,6,6,5,4,3,2,1,4,3,2,1,6,5)

df <- data.frame(set,pos,inf, expected_pos)

#Finding the maximum
library(dplyr)
result_df <- df %>%
   group_by(set) %>%
   mutate(result = (inf == max(inf)))
   result_vec <- result_df[which(result_df$result),c(1,2,3)]

  #Finding second highest position
pos1 <- result_vec
pos2 <- array(NA,dim=c(3,3))
   for(i in 1:3)     
   {   
   if(pos1[i,2]==1) pos2[i,c(2,3)] <- c(which(result_df$inf[((i-1)*6+1):((i-1)*6+6)]==max(c(result_df$inf[(i-1)*6+2],result_df$inf[(i-1)*6+6]))),max(c(result_df$inf[(i-1)*6+2],result_df$inf[(i-1)*6+6]))) #Position 2, 6

  if(pos1[i,2]==6) pos2[i,c(2,3)] <- c(which(result_df$inf[((i-1)*6+1):((i-1)*6+6)]==max(c(result_df$inf[(i-1)*6+1],result_df$inf[(i-1)*6+5]))), max(c(result_df$inf[(i-1)*6+1],result_df$inf[(i-1)*6+5]))) #Position 5, 1

  if(pos1[i,2] %in% c("2","3","4","5")) pos2[i,c(2,3)] <- c(which(result_df$inf[((i-1)*6+1):((i-1)*6+6)]==max(c(result_df[result_df$set == as.numeric(pos1[i,1]) & result_df$pos == as.numeric(pos1[i,2]-1),]$inf, result_df[result_df$set == as.numeric(pos1[i,1]) & result_df$pos == as.numeric(pos1[i,2]+1),]$inf))), max(c(result_df[result_df$set == as.numeric(pos1[i,1]) & result_df$pos == as.numeric(pos1[i,2]-1),]$inf, result_df[result_df$set == as.numeric(pos1[i,1]) & result_df$pos == as.numeric(pos1[i,2]+1),]$inf)))
  #Position above or below the focal number pos1
   }

不确定我的解决方案是否过于复杂,但您可以尝试

bucket_direction <- function(x, y) {
   order_pos <- order(x, decreasing = TRUE)
   first_pos <- y[order_pos[1L]]
   second_pos <- y[order_pos[2L]]
   if (second_pos < first_pos) {
     temp <- max(order_pos) - first_pos
     c(first_pos:1, rep(max(order_pos), temp) - seq_len(temp) + 1)
    }
    else {
     temp <- first_pos - min(order_pos)
     c(first_pos:6, rep(min(order_pos), temp) + seq_len(temp) - 1)
  }
}

然后为每个 set

应用函数
library(dplyr)
df %>% group_by(set) %>% mutate(res = bucket_direction(inf, pos))

#    set   pos   inf expected_pos   res
#   <dbl> <dbl> <dbl>        <dbl> <dbl>
# 1     1     1  1000            1     1
# 2     1     2   200            2     2
# 3     1     3     3            3     3
# 4     1     4     4            4     4
# 5     1     5     5            5     5
# 6     1     6     6            6     6
# 7     2     1     1            6     6
# 8     2     2     2            5     5
# 9     2     3     3            4     4
#10     2     4     4            3     3
#11     2     5   500            2     2
#12     2     6  6000            1     1
#13     3     1     1            4     4
#14     3     2     2            3     3
#15     3     3   300            2     2
#16     3     4  4000            1     1
#17     3     5     5            6     6
#18     3     6     6            5     5