如何通过R dataframe中每个id的百分位数对有序数据进行二进制[r]

时间:2011-10-06 02:25:59

标签: r dataframe percentile

我的数据框包含70-80行有序响应时间(rt)数据,每个人有228个人,每个人都有一个唯一的ID#(每个人都没有相同的行数)。我想把每个人的RT分成5个箱子。我希望第一个bin是他们最快20%的RT,第二个bin是他们下一个最快的20%RT,等等。每个bin应该有相同数量的试验(除非试用的总数是奇数)。

我目前的数据框如下所示:

id     RT
7000   225
7000   250
7000   253
7001   189
7001   201
7001   225

我希望我的新数据框看起来像这样:

id   RT    Bin
7000  225    1
7000  250    1

在我的数据看起来像这样之后,我将通过id和bin

进行聚合

我能想到的唯一方法是将数据拆分为一个列表(使用split命令),遍历每个人,使用quantile命令获取不同bin的断点,分配bin值(1-5)到每个响应时间。这感觉非常复杂(对我来说很难)。我有点陷入困境,我非常感谢如何简化这一过程。谢谢。

3 个答案:

答案 0 :(得分:4)

答案@Chase将范围分成5组相等长度(端点差异)。你似乎想要的是pentiles(每组5组,数量相同)。为此,您需要cut2

中的Hmisc功能
library("plyr")
library("Hmisc")

dat <- data.frame(id = rep(1:10, each = 10), value = rnorm(100))

tmp <- ddply(dat, "id", transform, hists = as.numeric(cut2(value, g = 5)))

tmp现在有了你想要的东西

> tmp
    id       value hists
1    1  0.19016791     3
2    1  0.27795226     4
3    1  0.74350982     5
4    1  0.43459571     4
5    1 -2.72263322     1
....
95  10 -0.10111905     3
96  10 -0.28251991     2
97  10 -0.19308950     2
98  10  0.32827137     4
99  10 -0.01993215     4
100 10 -1.04100991     1

每个hists

的每个id使用相同的数字
> table(tmp$id, tmp$hists)

     1 2 3 4 5
  1  2 2 2 2 2
  2  2 2 2 2 2
  3  2 2 2 2 2
  4  2 2 2 2 2
  5  2 2 2 2 2
  6  2 2 2 2 2
  7  2 2 2 2 2
  8  2 2 2 2 2
  9  2 2 2 2 2
  10 2 2 2 2 2

答案 1 :(得分:3)

以下是使用包plyrcut函数的可重现示例:

dat <- data.frame(id = rep(1:10, each = 10), value = rnorm(100))

ddply(dat, "id", transform, hists = cut(value, breaks = 5))

    id       value             hists
1    1 -1.82080027     (-1.94,-1.41]
2    1  0.11035796     (-0.36,0.166]
3    1 -0.57487134    (-0.886,-0.36]
4    1 -0.99455189    (-1.41,-0.886]
....
96  10 -0.03376074    (-0.233,0.386]
97  10 -0.71879488   (-0.853,-0.233]
98  10 -0.17533570    (-0.233,0.386]
99  10 -1.07668282    (-1.47,-0.853]
100 10 -1.45170078    (-1.47,-0.853]

如果您想要返回简单的整数值而不是分档,请将labels = FALSE传递给cut

答案 2 :(得分:0)

以下是普通老R的答案。

#make up some data
df <- data.frame(rt = rnorm(60), id = rep(letters[1:3], rep(20)) )

#and this is all there is to it
df <- df[order(df$id, df$rt),]
df$bin <- rep( unlist( tapply( df$rt, df$id, quantile )), each = 4)

您将注意到所使用的quantile命令可以设置为使用任何分位数。默认值适用于五分位数但如果您需要十分位数则使用

quantile(x, seq(0, 1, 0.1))

在上面的函数中。

上面的答案有点脆弱。它需要相同数量的RT / id,我没有告诉你如何获得神奇的数字4.但是,它也会在大型数据集上运行得非常快。如果您想在基础R中获得更强大的解决方案。

library('Hmisc')
df <- df[order(df$id),]
df$bin <- unlist(lapply( unique(df$id), function(x) cut2(df$rt[df$id==x], g = 5) ))

这比第一个解决方案更强大,但速度并不快。对于小型数据集,您将不会注意到。