Как расширить большой фрейм данных в R

У меня есть датафрейм

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

Я хочу расширить его, чтобы была каждая комбинация id и spp и y = 0 для каждой комбинации, которой в данный момент нет в кадре данных. В настоящее время кадр данных составляет около 100 000 строк и 15 столбцов. При расширении это будет около 300 000 столбцов (в моем фактическом наборе данных есть 17 уникальных значений spp).

Для каждого значения id date одинаково (например, когда id = 2, дата всегда = 1985-08-01). В моем реальном наборе данных все столбцы, кроме spp и y, могут быть указаны с помощью id.

Я хочу закончить что-то вроде:

   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*
  • Указать добавленные строки

Вероятно, мне придется сделать это в будущем с потенциально гораздо большими кадрами данных, поэтому быстрый и эффективный (время и память) способ сделать это будет оценен, но любое решение удовлетворит меня. Я полагаю, что должны быть способы использования пакетов dplyr, data.table или reshape, но я не очень хорошо знаком ни с одним из них. Я не уверен, что было бы проще всего расширить только строки id, spp и y, а затем выполнить left_join() или merge() для рекомбинации даты (и всех других переменных в моем реальном фрейме данных) на основе id?


person djhocking    schedule 27.02.2014    source источник


Ответы (3)


expand.grid здесь полезная функция,

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

Поскольку вы на самом деле ничего не делаете с подмножествами данных, я не думаю, что plyr поможет, возможно, более эффективные способы с data.table.

person Rorschach    schedule 27.02.2014

Я бы пошел вторым путем, надеюсь, это поможет

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)
person Ananta    schedule 27.02.2014

В разрабатываемой версии tidyr есть новая функция complete, которая делает это. Конечно, complete использует expand.grid внутри.

# 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
person shadow    schedule 22.05.2015