2011-10-06 108 views
4

我有一个数据框,其中包含70-80行有序响应时间(rt)数据,每个228个人每个都有唯一的ID#(每个人都有没有相同数量的行)。我想把每个人的RTs分成5个垃圾箱。我希望第一仓是他们最快的20%,第二仓是他们下一个最快的20%RT等等,等等。每个仓都应该有相同数量的试验(除非试验的总数是奇数)。如何在R数据框中按每个百分点排序数据[r]

我现在的数据帧是这样的:

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命令),循环遍历每个人,使用分位数命令获得断点f或不同仓位,为每个响应时间分配仓值(1-5)。这感觉非常复杂(对我来说很难)。我遇到了一些困难,如果能够简化这一过程,我将不胜感激。谢谢。

回答

4

答案@Chase将范围分成5组长度相等(端点不同)。你似乎想要的是pentiles(每组5个组数相同)。对于这一点,你需要在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的cut2功能现在有你想要什么

> 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 
+0

是的!我是对的,谢谢你的补充。 (如果不清楚,请参阅下面的评论) – Chase

+0

抱歉,@Chase,在我开始撰写此文章之前,我没有看到您的评论。 –

+0

不用担心,它需要一个村庄...... :) – Chase

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 = FALSEcut,如果你想简单的整数值返回而不是垃圾箱。

+0

也许我的问题是不清楚,对于每个ID,我希望将相同数量的试验分成5个分箱。例如,一个有80 rts的人将有16个试验的5个仓,仓1是最快的16个试验,仓5是最慢的。你知道一种方法来完成这个吗? – Matt

+0

@马特蔡斯的答案正是你所描述的。你甚至尝试过吗? – joran

+0

我做到了。我赞赏Chases的解决方案。但我最初的要求并不清楚。我需要每个bin都由相同数量的rts组成。在Chases解决方案中,hist创建了5个bin,但每个都由不同数量的rts组成。 – Matt

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))) 

一个更强大的解决方案这比第一个解决方案更强大,但它是没有那么快。对于小数据集,你不会注意到。

+0

这个汇总命令返回的值是什么?我想要的是每个id的5个值,第一个值是该id最快的x次试验的平均值,下一个bin是他们下一个最快的x次试验。每个垃圾箱应由相同数量的试验组成(当试验总次数为偶数时)。 – Matt

+0

看到应该做你想做的修改 – John

+0

谢谢,约翰。我已经运行了您的修改解决方案我不明白的是为什么rts没有提升。切割点中包含的值的平均值应该随着切割点变大而增加,否? – Matt