【问题标题】:how to bin computed data by percentile in an R data frame如何在 R 数据框中按百分位数对计算数据进行分类
【发布时间】:2014-01-07 22:53:52
【问题描述】:

我有一个包含大量符号、日期和值的数据框

date         symbol value
2014-01-03     A      2.5
2014-01-04     A      3.1
2014-01-06     A      4.5
2014-01-03     B      2.6
2014-01-05     B      3.2
2014-01-06     B      4.3

我想按符号拆分数据,计算 2 个最近日期的百分比变化,并按一些可变数量的组对数据进行分类,其中第一组具有最大的 pct 集。变化,下一个是第二大的,依此类推。每个组需要具有大致相同数量的符号。

理想情况下,我希望我的新数据框看起来像这样

date         symbol value       pctchg     bin
2014-01-03     A      2.5       .45161      1
2014-01-04     A      3.1       .45161      1
2014-01-06     A      4.5       .45161      1
2014-01-03     B      2.6       .34375      2
2014-01-05     B      3.2       .34375      2
2014-01-06     B      4.3       .34375      2

对于 ddply 来说,这似乎是一项完美的任务,但我正在努力让某些东西发挥作用。任何建议将不胜感激。感谢您的时间和帮助。

【问题讨论】:

  • 您好,欢迎来到 stackoverflow!感谢您提供一个小的虚拟数据集和所需的结果。请注意,如果您展示您已经尝试过的代码以及出了什么问题,人们通常会更乐意提供帮助(参见例如herehere)。干杯。

标签: r dataframe binning


【解决方案1】:

我不是一个经验丰富的程序员,但我会推荐这个候选人:

df <- read.table(sep=" ", header=T, text="
date symbol value
2014-01-03 A 2.5
2014-01-04 A 3.1
2014-01-06 A 4.5
2014-01-03 B 2.6
2014-01-05 B 3.2
2014-01-06 B 4.3")

library(plyr)
df <- df[order(df$symbol, df$date),]
df <- ddply(df, "symbol", transform, pctchg=value[length(value)]/value[length(value)-1]-1)
df <- df[order(-df$pctchg),]

bins <- 2

library(ggplot2)
groups <- cut_number(1:length(unique(df$pctchg)), n=bins)
levels(groups) <- 1:length(levels(groups))
df <- merge(x=df, y=cbind.data.frame(symbol=unique(df$symbol), bin=groups))
df[order(-df$pctchg),]
#   symbol       date value    pctchg bin
# 1      A 2014-01-03   2.5 0.4516129   1
# 2      A 2014-01-04   3.1 0.4516129   1
# 3      A 2014-01-06   4.5 0.4516129   1
# 4      B 2014-01-03   2.6 0.3437500   2
# 5      B 2014-01-05   3.2 0.3437500   2
# 6      B 2014-01-06   4.3 0.3437500   2

【讨论】:

    【解决方案2】:

    改编自 LukeA 的回答,作为更规范的 plyr 解决方案。

    如果您要使用plyr,请致电arrange 而不是order

    df <- arrange(df, symbol, date)
    

    pctchg 的代码不太正确。要匹配问题中的输出,请使用

    df2 <- ddply(
      df,
      .(symbol), 
      mutate, 
      pctchg = (value[length(value)] - value[length(value)-1]) / value[length(value)-1]
    )
    

    (还要注意使用mutate 而不是transform。可以使用基于factor 函数的hack 来生成垃圾箱。

    mutate(df2, bin = as.integer(factor(-pctchg)))
    

    【讨论】:

      【解决方案3】:

      假设 data.frame DF 已经按照问题中的 symboldate 排序,f 计算其向量参数和 ave 的最后两个值的变化将其应用于每个组。最后我们使用order 重新排序并附加bin。我们使用了标题relchg 而不是pctchg,因为问题中显示的值不是百分比。

      f <- function(x) { n <- length(x); if (n > 1) x[n] / x[n-1] - 1 else NA }
      DF2 <- transform(DF, relchg = ave(value, symbol, FUN = f))
      o <- with(DF2, order(-relchg, symbol, date))
      transform(DF2[o, ], bin = as.numeric(factor(symbol, levels = unique(symbol))))
      

      结果是:

              date symbol value    relchg bin
      1 2014-01-03      A   2.5 0.4516129   1
      2 2014-01-04      A   3.1 0.4516129   1
      3 2014-01-06      A   4.5 0.4516129   1
      4 2014-01-03      B   2.6 0.3437500   2
      5 2014-01-05      B   3.2 0.3437500   2
      6 2014-01-06      B   4.3 0.3437500   2
      

      【讨论】:

      • 在最后一行代码中,我认为bin应该基于pctchg,而不是symbol
      • 只有在我们知道没有两个符号具有相同的 chg 但我们不知道的情况下才能做到这一点。它的工作方式更普遍。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-06
      • 2016-01-01
      • 2012-09-16
      • 1970-01-01
      • 1970-01-01
      • 2017-04-26
      • 2013-01-14
      相关资源
      最近更新 更多