【问题标题】:R : Create specific bin based on data rangeR : 根据数据范围创建特定的 bin
【发布时间】:2015-06-09 17:05:11
【问题描述】:

我正在尝试根据指定的 bin 大小向数字向量重复添加“固定数字”。但是,“固定数量”取决于数据范围。

例如;我的数据范围是 10 到 1010,我希望将数据分成 100 个 bin。因此,理想情况下,数据应该是这样的

Since 1010 - 10 = 1000
And 1000 / 100(The number of bin specified) = 10
Therefore the ideal data would look like this
bin1 - 10 (initial data)  
bin2 - 20 (initial data + 10)  
bin3 - 30 (initial data + 20)  
bin4 - 40 (initial data + 30)    
bin100 - 1010 (initial data + 1000) 

现在真实数据稍微复杂一点,不是只有一个数据范围,而是多个数据范围,希望下面的例子能澄清一下

# Some fixed values
start <- c(10, 5000, 4857694)
end <- c(1010, 6500, 4897909)

理想情况下,我希望得到类似的东西

10  20
20  30
30  40
..   ..
5000  5015
5015  5030
5030  5045
..   ..
4857694   4858096 # Note theoretically it would have decimal places, 
#but i do not want any decimal place
4858096   4858498
..   ..

到目前为止,我一直在考虑这种功能,但它似乎效率低下,因为 ;
1) 我必须重新输入函数 100 次(因为我的 bin 数是 100)
2)我找不到一种方法来沿着我的值重复该函数 - 换句话说,我的函数只能处理数据 10-1010 而不能处理下一个 5000-6500

# The range of the variable
width <- end - start
# The bin size (Number of required bin)
bin_size <- 100
bin_count <- width/bin_size
# Create a function
f1 <- function(x,y){
c(x[1],
x[1] + y[1], 
x[1] + y[1]*2,
x[1] + y[1]*3)
}

f1(x= start,y=bin_count)
f1
[1] 10 20 30 40

也许任何提示或想法将不胜感激。提前致谢!

【问题讨论】:

  • 在您的示例中,您将bin4 显示为数据+ 300,将bin100 显示为数据+ 1000。你的意思是bin11bin3 (+200) bin4 (+300) bin5 (+400) bin6 (+500) bin7 (+600) bin8 (+700) bin9 (+800) bin10 (+900) bin11 (+1000)
  • 如果您想要 100 个 bin,您必须在每个初始数据中添加 10 bin1 10 bin2 10+10 bin3 10 + 20 bin100 1000 +10
  • 抱歉,问题已更正。非常感谢@plafort
  • 我添加了一个可能提供您想要的输出的答案

标签: r bin


【解决方案1】:

经过几个小时的尝试,设法回答了我自己的问题,所以我想分享一下。我使用包“binr”和包中名为“bins”的函数来获取所需的 bin。请在下面找到我试图回答我的问题的尝试,它与预期的输出略有不同,但出于我的目的,它仍然可以

library(binr)
# Some fixed values
start <- c(10, 5000, 4857694)
end <- c(1010, 6500, 4897909)

tmp_list_start <- list() # Create an empty list

# This just extract the output from "bins" function into a list
for (i in seq_along(start)){
  tmp <- bins(start[i]:end[i],target.bins = 100,max.breaks = 100)
  # Now i need to convert one of the output from bins into numeric value
  s <- gsub(",.*", "", names(tmp$binct))
  s <- gsub("\\[","",s)
  tmp_list_start[[i]] <- as.numeric(s)
}  

# Repeating the same thing with slight modification to get the end value of the bin
tmp_list_end <- list()
for (i in seq_along(end)){
  tmp <- bins(start[i]:end[i],target.bins = 100,max.breaks = 100)
  e <- gsub(".*,", "", names(tmp$binct))
  e <- gsub("]","",e)
  tmp_list_end[[i]] <- as.numeric(e)
}

v1 <- unlist(tmp_list_start)
v2 <- unlist(tmp_list_end)

df <- data.frame(start=v1, end=v2)
head(df)
  start end
1    10  20
2    21  30
3    31  40
4    41  50
5    51  60
6    61  70

请原谅我糟糕的代码,如果有更好的方法,请分享。如果有人可以评论如何将其包装到函数中会很好..

【讨论】:

    【解决方案2】:

    这是一种可能对基础R 有所帮助的方法:

    bin_it <- function(START, END, BINS) {
      range <- END-START
      jump <- range/BINS
      v1 <- c(START, seq(START+jump+1, END, jump))
      v2 <- seq(START+jump-1, END, jump)+1
      data.frame(v1, v2)
    }
    

    它使用函数seq 来创建通向结束数字的数字向量。它可能不适用于所有情况,但对于您提供的范围,它应该会提供所需的输出。

    bin_it(10, 1010)
          v1   v2
    1     10   20
    2     21   30
    3     31   40
    4     41   50
    5     51   60
    
    bin_it(5000, 6500)
          v1   v2
    1   5000 5015
    2   5016 5030
    3   5031 5045
    4   5046 5060
    5   5061 5075
    
    bin_it(4857694, 4897909)
             v1      v2
    1   4857694 4858096
    2   4858097 4858498
    3   4858499 4858900
    4   4858901 4859303
    5   4859304 4859705
    6   4859706 4860107
    

    【讨论】:

    • 太棒了!!! 2 更容易理解和理解。谢谢@plafort!不知道“序列”。再次干杯!我认为您错过了在答案中包含 BINS 参数:) -> 应该是 bin_it(10, 1010, #bin)
    • 我试过了,但是“投票需要 15 声望”,我有 0 :(
    • 在上下投票的下方,有一个V形图像。点击接受答案。
    猜你喜欢
    • 2022-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多