Questão
Usando dplyr
, como faço para selecionar as observações / linhas superior e inferior dos dados agrupados em uma instrução?
Dados e exemplo
Dado um quadro de dados
df <- data.frame(id=c(1,1,1,2,2,2,3,3,3),
stopId=c("a","b","c","a","b","c","a","b","c"),
stopSequence=c(1,2,3,3,1,4,3,1,2))
Posso obter as observações superior e inferior de cada grupo usando slice
, mas usando duas declarações separadas:
firstStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(1) %>%
ungroup
lastStop <- df %>%
group_by(id) %>%
arrange(stopSequence) %>%
slice(n()) %>%
ungroup
Posso combinar esses dois conjuntos de estatísticas em um que selecione as observações superior e inferior?
Respostas:
Provavelmente existe uma maneira mais rápida:
fonte
rownumber() %in% c(1, n())
evitaria a necessidade de executar vector varredura duas vezes_
? iefilter(row_number() %in% c(1, n()))
Apenas para completar: você pode passar
slice
um vetor de índices:que dá
fonte
filter
- não testei isso, mas veja aquimtcars[1, ] %>% slice(c(1, n()))
nesse sentido, a escolha entre elas depende do que você deseja devolver. Eu esperaria que os horários fossem próximos, a menos quen
seja muito grande (onde a fatia pode ser favorecida), mas também não foram testados.Não
dplyr
, mas é muito mais direto usandodata.table
:Explicação mais detalhada:
Certifique-se de verificar o wiki Introdução para obter o
data.table
básico cobertofonte
df[ df[order(stopSequence), .I[c(1,.N)], keyby=id]$V1 ]
. Verid
aparecer duas vezes é estranho para mim.setDT
chamada. Portanto, umaorder
ligação não é necessária aqui.df[order(stopSequence), .SD[c(1L,.N)], by = id]
. Veja aquiid
. Eu acho quedf[order(stopSequence), .SD[c(1L, .N)], keyby = id]
deve fazer o truque (com a pequena diferença para a solução acima que o resultado serákey
edAlgo como:
Com
do
você, você pode executar qualquer número de operações no grupo, mas a resposta do @ jeremycg é muito mais apropriada para essa tarefa.fonte
slice
, comodf %>% arrange(stopSequence) %>% group_by(id) %>% slice(c(1,n()))
do
exemplo aqui pode ajudar outras pessoas quandoslice
não funcionar (ou seja, operações mais complexas em um grupo). E você deve postar seu comentário como resposta (é o melhor).Eu sei a pergunta especificada
dplyr
. Mas, como outros já postaram soluções usando outros pacotes, decidi usar outros pacotes também:Pacote base:
Tabela de dados:
sqldf:
Em uma consulta:
Resultado:
fonte
usando
which.min
ewhich.max
:referência
Também é muito mais rápido que a resposta atualmente aceita, porque encontramos o valor mínimo e máximo por grupo, em vez de classificar toda a coluna stopSequence.
fonte
Usando
data.table
:fonte
Outra abordagem com lapply e uma declaração dplyr. Podemos aplicar um número arbitrário de quaisquer funções de resumo à mesma declaração:
Por exemplo, você pode estar interessado em linhas com o valor máximo de stopSequence e fazer:
fonte
Uma alternativa base de R diferente seria a primeira
order
porid
estopSequence
,split
-los com base emid
e para cadaid
selecionamos apenas o primeiro eo último índice e subconjunto da trama de dados usando esses índices.Ou similar usando
by
fonte