Выбор первых n-ых строк по группе с изменением количества строк - PullRequest
4 голосов
/ 07 марта 2011

Мне нравится выбирать первые (2,3,0,4) строки каждой группы в кадре данных.

> f<-data.frame(group=c(1,1,1,2,2,3,4),y=c(1:7))
> 
>   group y
>      1 1
>      1 2
>      1 3
>      2 4
>      2 5
>      3 6
>      4 7

и получать кадр данных следующим образом

group y
1 1
1 2
2 4
2 5
4 7

Я пытался использовать by и head, но голова не берет вектор.

Спасибо за вашу помощь.

Ответы [ 3 ]

5 голосов
/ 07 марта 2011

С более традиционными lapply:

k <- c(2,3,0,4)
fs <- split(f, f$group)
do.call(rbind,lapply(seq_along(k), function(i) head(fs[[i]], k[i])))

результат:

  group y
1     1 1
2     1 2
4     2 4
5     2 5
7     4 7
2 голосов
/ 07 марта 2011

Использование plyr:

library(plyr)
rows <- c(2,3,0,4)
ddply(f,.(group),function(x)head(x,rows[x[1,1]]))
        group y
    1     1 1
    2     1 2
    3     2 4
    4     2 5
    5     4 7

редактирование:

неправильно понял вопрос обновленный ответ

1 голос
/ 08 марта 2011

Версия функции с индексами.

fun1 <- function(){
  idx <- c(0,which(diff(f$group)!=0))+1
  idx2 <- unlist(lapply(1:length(nf),function(x)  seq.int(from=idx[x],length.out=nf[x])),use.names=F)
  f1 <- f[idx2,]
  return(f1)
}

fun2 <- function(){
  ddply(f,.(group),function(x) head(x,nf[x[1,1]]))
}

Тестовые данные (размер, предложенный автором вопроса)

f<-data.frame(group=sample(1:1000,50000,T),y=c(1:50000))
f <- f[order(f$group),]
nf <- rpois(length(unique(f$group)),3) 

system.time (fun1 ()) system.time (fun2())

В моей системе ~ 60 раз быстрее, это весело1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...