【问题标题】:Group/bin/bucket data in R and get count per bucket and sum of values per bucketR中的分组/bin/bucket数据并获取每个桶的计数和每个桶的值总和
【发布时间】:2015-03-01 23:48:18
【问题描述】:

我希望存储/分组/分箱数据:

C1             C2       C3
49488.01172    0.0512   54000
268221.1563    0.0128   34399
34775.96094    0.0128   54444
13046.98047    0.07241  61000
2121699.75     0.00453  78921
71155.09375    0.0181   13794
1369809.875    0.00453  12312
750            0.2048   43451
44943.82813    0.0362   49871
85585.04688    0.0362   18947
31090.10938    0.0362   13401
68550.40625    0.0181   14345

我想按 C2 值对它进行存储,但我希望定义存储桶,例如

我不知道从哪里开始,因为我是 R 的新用户。有没有人愿意帮助我找出代码或指导我提供一个可以满足我需求的示例?

编辑:添加了另一列 C3。我需要每个桶的 C3 总和以及每个桶 C1 的总和和计数

【问题讨论】:

  • 通常情况下,当你发帖时,让人们知道你这样做是礼貌talkstats.com/showthread.php/…
  • 谢谢 Tyler,这是两个不同的网站,所以我不会认为这是必要的
  • @user3007275 你还想用C2 作为分组变量吗?
  • 是的,C2 仍然是分组变量
  • 感谢 akrun,有趣的是 R 如何整体处理 do.call 语句。现在您已经对两个变量 C1 和 C3 进行了分组,FUN 仍然只使用一个运算符 X 而不是两个 -one 分别用于 C1 和 C3。这里的逻辑是什么?

标签: r aggregate binning


【解决方案1】:

从 cmets 来看,“C2”似乎是“字符”列,后缀为 %。在创建组之前,使用sub 删除%,转换为“数字”(as.numeric)。变量“组”是通过使用带有breaks(组桶/间隔)和labels(用于所需组标签)参数的函数cut创建的(transform(df,...))。一旦创建了组变量,“组”的“C1”的sum和“组”中元素的“计数”可以使用“base R”中的aggregate来完成

df1 <-  transform(df, group=cut(as.numeric(sub('[%]', '', C2)), 
    breaks=c(-Inf,0.005, 0.010, 0.014, Inf),
      labels=c('<0.005', 0.005, 0.01, 0.014)))

 res <- do.call(data.frame,aggregate(C1~group, df1, 
        FUN=function(x) c(Count=length(x), Sum=sum(x))))

 dNew <- data.frame(group=levels(df1$group))
 merge(res, dNew, all=TRUE)
 #   group C1.Count    C1.Sum
 #1 <0.005        2 3491509.6
 #2  0.005       NA        NA
 #3   0.01        2  302997.1
 #4  0.014        8  364609.5

或者您可以使用data.tablesetDTdata.frame 转换为 data.table。使用by= 指定“分组”变量,并在list( 中汇总/创建两个变量“Count”和“Sum”。 .N 给出每个“组”中元素的数量。

 library(data.table)
  setDT(df1)[, list(Count=.N, Sum=sum(C1)), by=group][]

或使用dplyr%&gt;% 将 LHS 与 RHS 参数连接起来,并将它们链接在一起。使用group_by 指定“组”变量,然后使用summarise_eachsummarise 获取相关列的汇总计数和sum。如果有不止一列,summarise_each 会很有用。

 library(dplyr)
 df1 %>%
      group_by(group) %>% 
      summarise_each(funs(n(), Sum=sum(.)), C1)

更新

使用新数据集df

df1 <- transform(df, group=cut(C2,  breaks=c(-Inf,0.005, 0.010, 0.014, Inf),
                             labels=c('<0.005', 0.005, 0.01, 0.014)))

res <- do.call(data.frame,aggregate(cbind(C1,C3)~group, df1, 
       FUN=function(x) c(Count=length(x), Sum=sum(x))))
res
#  group C1.Count    C1.Sum C3.Count C3.Sum
#1 <0.005        2 3491509.6        2  91233
#2   0.01        2  302997.1        2  88843
#3  0.014        8  364609.5        8 268809

您可以按照上面的详细信息发送merge

dplyr 方法是相同的,只是指定了附加变量

 df1%>%
      group_by(group) %>%
       summarise_each(funs(n(), Sum=sum(.)), C1, C3)
 #Source: local data frame [3 x 5]

 #  group C1_n C3_n    C1_Sum C3_Sum
 #1 <0.005    2    2 3491509.6  91233
 #2   0.01    2    2  302997.1  88843
 #3  0.014    8    8  364609.5 268809

数据

df <-structure(list(C1 = c(49488.01172, 268221.1563, 34775.96094, 
13046.98047, 2121699.75, 71155.09375, 1369809.875, 750, 44943.82813, 
85585.04688, 31090.10938, 68550.40625), C2 = c("0.0512%", "0.0128%", 
"0.0128%", "0.07241%", "0.00453%", "0.0181%", "0.00453%", "0.2048%", 
"0.0362%", "0.0362%", "0.0362%", "0.0181%")), .Names = c("C1", 
"C2"), row.names = c(NA, -12L), class = "data.frame")

【讨论】:

  • 感谢 akrun,我也在尝试理解您提供的代码的逻辑/含义。我发现第一个比其他两个更容易理解。是否有资源(书籍/网站)可供我参考这 3 条建议,以了解正在发生的事情并可能看到一两个应用示例?
  • 谢谢,我刚刚尝试了第一个建议。 C2 实际上是百分比,所以当我输入 % 符号时,breaks=c(-Inf,0.005%,0.10%,0.014%,Inf) 出现错误。如果不使用 % 符号,它会起作用。此外,在分箱后,我需要将此数据绘制为直方图。我如何表示类别,例如
  • 阿克伦,谢谢。我尝试了第一个代码,它似乎有效。我将再次检查输出。我注意到它所做的一件事是,如果给定的 bin 没有值,它会从输出中省略该 bin。无论是否有任何值,我都想拥有所有的垃圾箱。
  • Akrun,我刚刚注意到您的代码将 C2 作为字符列。实际上它是一个数值(以%为单位)。我只想将它标记为百分比,但数据保持原样。我使用了您发布的第一个代码。为什么需要创建一个新数据集,然后将其与旧数据集合并? dNew 在做什么? (这部分代码背后的逻辑)
  • @user3007275 但是,您说数据以% 作为后缀(或者我可能误解了)。如果已经是数值列,可以使用我之前的代码。 dNew 具有所有级别,而原始数据集可能没有基于groupings。因此,如果没有特定组,聚合将不会返回该组。通过与dNew 合并,可以确保获得该组合。
猜你喜欢
  • 2017-09-16
  • 2023-03-15
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
  • 1970-01-01
  • 2023-02-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多