有没有一种方法可以为每行数据创建唯一的bin?

时间:2020-03-23 18:05:59

标签: r dplyr binning

我有一个数据集,其中包含多个对象的最小和最大高度。数据框如下所示:

ID Min Max  
A  30  160  
B  12  200  
C  35  171  
D  16  198 

我想在最小和最大之间划分距离,以创建3个容器“底部”,“中间”和“顶部”。我希望垃圾箱代表最小和最大之间范围的1/3。这是我的预期输出(小数还可以,我在这里取整):

ID Bottom Middle Top   
A  30-73  74-116 117-160  
B  12-75  76-137 138-200  
C  35-80  81-125 126-171  
D  16-77  78-138 139-198

在dplyr中有办法吗?

此外,我将使用从这些bin中创建的范围与这些范围内每个唯一ID的另一个单独的跟踪粒子运动的数据集进行比较。我想知道每个粒子位于“底部”,“中间”或“顶部”的频率。有没有办法对单独的文件执行此操作,还是应该以某种方式将它们组合在一起?

2 个答案:

答案 0 :(得分:0)

    library(dplyr)
    library(stringr)

    dataset <- data.frame(ID = c("A", "B", "C", "D"),
                          Min = c(30, 12, 35, 16),
                          Max = c(160, 200, 171, 198))

    datasetBins <- dataset %>%
# Getting bins limits (using floor() to make them separable)
      mutate(quater = (Max - Min) / 3) %>%
      mutate(limit2 = floor(Min + quater),
             limit3 = floor(Min + 2* quater)) %>%
# Creating bins (using +1 to make them separable)
      mutate(Bottom = str_c(Min, limit2, sep = "-"),
             Middle = str_c(limit2+1, limit3, sep = "-"),
             Top = str_c(limit3+1, Max, sep = "-")) %>%
# Droping redundant cols
      select(ID, Bottom, Middle, Top)

或者,如果您希望该数据框在与数值比较时有用,那么我将停止极限计算。然后,您可以使用ifelse()来检查连续数限制,以将给定值放置在正确的bin中。

答案 1 :(得分:0)

这是通过定义自定义函数f

的基本R解决方案
f <- Vectorize(function(l,u) {
  ur <- round((u-l)/3*(1:3)+l)
  lr <- c(l,ur[1:2]+1)
  paste(lr,ur,sep = "-")
})

dfout <- cbind(df[1],
               `colnames<-`(t(f(df$Min,df$Max)),c("Bottom","Middle","Top")))

这样

> dfout
  ID Bottom Middle     Top
1  A  30-73 74-117 118-160
2  B  12-75 76-137 138-200
3  C  35-80 81-126 127-171
4  D  16-77 78-137 138-198

数据

df <- structure(list(ID = structure(1:4, .Label = c("A", "B", "C", 
"D"), class = "factor"), Min = c(30, 12, 35, 16), Max = c(160, 
200, 171, 198)), class = "data.frame", row.names = c(NA, -4L))