Pergunta

Eu tenho um dataframe

df <- data.frame(
  id = c(1, 1, 1, 2, 2, 3, 3, 3, 3, 4), 
  date = c("1985-06-19", "1985-06-19", "1985-06-19", "1985-08-01", 
           "1985-08-01", "1990-06-19", "1990-06-19", "1990-06-19", 
           "1990-06-19", "2000-05-12"), 
  spp = c("a", "b", "c", "c", "d", "b", "c", "d", "a", "b"),
  y = rpois(10, 5))

   id       date spp y
1   1 1985-06-19   a 6
2   1 1985-06-19   b 3
3   1 1985-06-19   c 7
4   2 1985-08-01   c 7
5   2 1985-08-01   d 6
6   3 1990-06-19   b 5
7   3 1990-06-19   c 4
8   3 1990-06-19   d 4
9   3 1990-06-19   a 6
10  4 2000-05-12   b 6

Quero expandi-lo para que haja todas as combinações de id e spp e tenha y = 0 para cada combinação que não está atualmente no dataframe.O dataframe tem atualmente cerca de 100.000 linhas e 15 colunas.Quando expandido, seriam cerca de 300.000 colunas (existem 17 valores exclusivos de spp no meu conjunto de dados real).

Para cada valor de id o date é o mesmo (ex.quando id = 2, data sempre = 01/08/1985).No meu conjunto de dados real, todas as colunas, exceto spp e y pode ser especificado pelo id.

Quero terminar com algo como:

   id       date spp y
   1 1985-06-19   a 6
   1 1985-06-19   b 3
   1 1985-06-19   c 7
   1 1985-06-19   d 0*
   2 1985-08-01   a 0*
   2 1985-08-01   b 0*
   2 1985-08-01   c 7
   2 1985-08-01   d 6
   3 1990-06-19   b 5
   3 1990-06-19   c 4
   3 1990-06-19   d 4
   3 1990-06-19   a 6
   4 2000-05-12   a 0*
   4 2000-05-12   b 6
   4 2000-05-12   c 0*
   4 2000-05-12   d 0*
  • Indicar linhas adicionadas

Provavelmente terei que fazer isso no futuro com quadros de dados potencialmente muito maiores, portanto, uma maneira rápida e eficiente (tempo e memória) de fazer isso seria apreciada, mas qualquer solução me satisfaria.Eu acho que deveria haver maneiras de usar o dplyr, data.table, ou reshape pacotes, mas não estou muito familiarizado com nenhum deles.Não tenho certeza se seria mais fácil expandir apenas as linhas id, spp e y e depois fazer um left_join() ou merge() recombinar a data (e todas as outras variáveis ​​no meu dataframe real) com base em id?

Foi útil?

Solução

expand.grid é uma função útil aqui,

mergedData <- merge(
    expand.grid(id = unique(df$id), spp = unique(df$spp)),
    df, by = c("id", "spp"), all =T)

mergedData[is.na(mergedData$y), ]$y <- 0

mergedData$date <- rep(levels(df$date),
                       each = length(levels(df$spp)))

Como você não está realmente fazendo nada com subconjuntos de dados, não acho plyr ajudará, talvez maneiras mais eficientes com data.table.

Outras dicas

Eu iria pelo segundo caminho, espero que isso ajude

x<-unique(df$id)
y<-unique(df$spp)
newdf<-data.frame(x=rep(x,each=length(y)),y=rep(y, length(x)))
merged<-merge(newdf, df, by.x=c(x,y), by.y=c("id","spp"), all=T)

Há uma nova função complete na versão de desenvolvimento do tidyr isso faz isso.Claro complete usa expand.grid internamente.

# get new version of tidyr
devtools::install_github("hadley/tidyr")
# load package
require(tidyr)
# calculations
complete(df, c(id, date), spp, fill = list(y = 0))
##    id       date spp y
## 1   1 1985-06-19   a 5
## 2   1 1985-06-19   b 3
## 3   1 1985-06-19   c 5
## 4   1 1985-06-19   d 0
## 5   2 1985-08-01   a 0
## 6   2 1985-08-01   b 0
## 7   2 1985-08-01   c 4
## 8   2 1985-08-01   d 9
## 9   3 1990-06-19   a 8
## 10  3 1990-06-19   b 3
## 11  3 1990-06-19   c 5
## 12  3 1990-06-19   d 6
## 13  4 2000-05-12   a 0
## 14  4 2000-05-12   b 3
## 15  4 2000-05-12   c 0
## 16  4 2000-05-12   d 0
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top