【问题标题】:Binning variable by set number of observations按设定的观察次数对变量进行分箱
【发布时间】:2018-09-14 18:14:28
【问题描述】:

快速提问。我以多种不同的方式对变量进行分类以进行探索性数据分析。假设我在 data.frame df 中有一个名为 var 的变量。

df$var<-c(1,2,8,9,4,5,6,3,6,9,3,4,5,6,7,8,9,2,3,4,6,1,2,3,7,8,9,0)

到目前为止,我采用了以下方法(代码如下):

#Divide into quartiles
df$var_quartile <- with(df, cut(var, breaks=quantile(var, probs=seq(0,1, by=.25)), include.lowest=TRUE))
# Values of var_quartile
> [0,3],[0,3],(7.25,9],(7.25,9],(3,5],(3,5],(5,7.25],[0,3],(5,7.25],(7.25,9],[0,3],(3,5],(3,5],(5,7.25],(5,7.25],(7.25,9],(7.25,9],[0,3],[0,3],(3,5],(5,7.25],[0,3],[0,3],[0,3]

#Bin into increments of 2
df$var_bin<- cut(df[['var']],2, include.lowest=TRUE, labels=1:2)
# Values of var_bin
> 1 1 2 2 1 2 2 1 2 2 1 1 2 2 2 2 2 1 1 1 2 1 1 1 2 2 2 1

我想做的最后一件事是将变量按时间顺序排序后分成 10 个观察值的部分。这是在找到中位数后进行拆分的相同方法(计数到中间观察值),只是我想以 10 个观察值为增量进行计数。

使用我的示例,这会将var 拆分为以下部分:

0,1,1,2,2,2,3,3,3,3
4,4,4,5,5,6,6,6,6,7
7,8,8,8,9,9,9

注意-- 我需要在非常大的数据集(通常是 3-6 百万个宽幅观察)中运行此操作。

我该怎么做?谢谢!

【问题讨论】:

  • 请提供可重现的数据。
  • @roody 我想你会在“plyr”包中找到很多这样的工作实用程序。您可以使用功能 'ddply' 和 'mutate' 功能为您的 bin idexes 创建各种新列。您还可以使用 'zoo' 包中的滚动函数将观察结果按 10 分组。
  • 如果数据看起来像:var &lt;- c( rep(1, 11), rep(2, 3), rep(3, 9), rep(4,20) ) 甚至 sample(1:10, 100, repl=TRUE),那么期望的结果是什么,因为我很确定其中一些值的计数大于 10。跨度>
  • @Dinre - 非常感谢!一个问题是我正在使用庞大的数据集进行此操作,ddply 似乎会窒息,所以我通常使用 data.table。
  • @DWin - 我的例子足够了吗?

标签: r


【解决方案1】:

cut_number() 来自 ggplot2 旨在将数字向量切割成包含相等数量点的区间。在您的情况下,您可以像这样使用它:

library(ggplot2)
split(var, cut_number(var, n=3, labels=1:3))
# $`1`
#  [1] 1 2 3 3 2 3 1 2 3 0
# 
# $`2`
# [1] 4 5 6 6 4 5 6 4 6
# 
# $`3`
# [1] 8 9 9 7 8 9 7 8 9

【讨论】:

  • (+1) 非常好用的功能!
【解决方案2】:
vec <- c(1,2,8,9,4,5,6,3,6,9,3,4,5,6,7,8,9,2,3,4,6,1,2,3,7,8,9,0) # your vector

nObs <- 10 # number of observations per bin

# create data labels
datLabels <- ceiling(seq_along(vec)/nObs)[rank(vec, ties.method = "first")] 


# test data labels:
split(vec, datLabels)

$`1`
 [1] 1 2 3 3 2 3 1 2 3 0

$`2`
 [1] 4 5 6 6 4 5 6 7 4 6

$`3`
 [1] 8 9 9 8 9 7 8 9

【讨论】:

  • (+1) 很好地使用了rank。我会记住的!
【解决方案3】:

你的意思是这样的吗?

x <- sample(100)
binSize <- 10
table(floor(x/binSize)*binSize)

【讨论】:

    【解决方案4】:

    我在不使用剪切的情况下创建了大小相等的组。

    # number_of_groups_wanted  = number of rows / divisor in ceiling code  
    # therefore divisor in ceiling code should be =  number of rows / number_of_groups_wanted, 
    # divisor in ceiling code = (nrow(df)/number_of_groups_wanted)  
    # min assigns every tied element to the lowest rank 
    number_of_groups_wanted = 100 # put in the number of groups you want
    df$group = ceiling(rank(df$var_to_group, ties.method = "min")/(nrow(df)/number_of_groups_wanted)) 
    
    df$rank = rank(df$var_to_group, ties.method = "min") # this line is just used to check data  
    

    【讨论】:

      【解决方案5】:

      应该这样做。

      df$var_bin<- cut(df[['var']], breaks = Size(df$var/10), 
                       include.lowest=TRUE, labels=1:10)
      

      【讨论】:

      • R 给了我错误could not find function "Size"。想法?
      • 尝试:'nrow(df$var)/10'
      猜你喜欢
      • 2017-06-29
      • 1970-01-01
      • 2017-06-04
      • 2011-01-31
      • 2016-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多