【问题标题】:Is there a way to create unique bins for each row of data?有没有办法为每行数据创建唯一的 bin?
【发布时间】:2020-03-23 18:05:59
【问题描述】:

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

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

我想分割 Min 和 Max 之间的距离,以创建 3 个 bin “Bottom”、“Middle”和“Top”。我希望这些垃圾箱代表最小值和最大值之间范围的 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 的粒子运动。我想知道每个粒子在“底部”、“中间”或“顶部”的频率。有没有办法用单独的文件来做到这一点,或者我应该以某种方式将它们组合起来?

【问题讨论】:

  • 你能显示预期的输出吗
  • 我添加了预期的输出

标签: r dplyr binning


【解决方案1】:
    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 中。

【讨论】:

    【解决方案2】:

    这是一个通过定义自定义函数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))
    

    【讨论】:

      猜你喜欢
      • 2015-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-25
      • 2013-10-14
      • 1970-01-01
      • 2013-10-30
      • 2021-03-19
      相关资源
      最近更新 更多