Как разместить упорядоченные данные по процентилю для каждого идентификатора в R dataframe [r] - PullRequest
4 голосов
/ 06 октября 2011

У меня есть фрейм данных, который содержит 70-80 строк данных о порядке времени отклика (rt) для каждого из 228 человек с уникальным идентификатором # (у всех не одинаковое количество строк).Я хочу поместить RT каждого человека в 5 корзин.Я хочу, чтобы 1-й бин был их самыми быстрыми 20-процентными RT, 2-й бин - их самыми быстрыми 20-процентными RT, и т. Д., И т. Д. В каждом бине должно быть одинаковое количество испытаний (если общее количество испытаний не является нечетным)).

Мой текущий фрейм данных выглядит следующим образом:

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), выполнить цикл по каждому человеку, использовать квантильКоманда, чтобы получить точки останова для разных бинов, назначить значение бина (1-5) для каждого времени ответа.Это кажется очень запутанным (и будет трудно для меня).Я в некотором затруднении, и я был бы очень признателен за любую помощь в том, как упростить этот процесс.Благодарю.

Ответы [ 3 ]

4 голосов
/ 06 октября 2011

Ответ @Chase дал разбить диапазон на 5 групп равной длины (разница конечных точек).То, что вы, кажется, хотите, это пентилы (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
3 голосов
/ 06 октября 2011

Вот воспроизводимый пример с использованием пакета plyr и функции cut:

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, если вы хотите, чтобы вместо целых значений возвращались простые целочисленные значения.

0 голосов
/ 06 октября 2011

Вот ответ в простой старой 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) ))

Это намного надежнее, чем первое решение, но не так быстро. Для небольших наборов данных вы не заметите.

...