Преобразуйте data.frame, заполняя пропущенные значения - PullRequest
2 голосов
/ 25 сентября 2011

у меня есть фрейм данных

data<-data.frame(id=c("A","A","B","B"), day=c(5,6,1,2), duration=c(12,1440,5,6), obs.period=c(60, 60,100,100))

показывает идентификатор субъекта, день события, продолжительность события и период наблюдения субъекта

Я хочу преобразовать набор данных таким образом, чтобы он отображал весь период наблюдения для каждого субъекта (все дни наблюдения), при этом добавляя ноль в качестве значений продолжительности для дней, в которых событие не наблюдалось

Для вышеуказанного набора данных это будет что-то вроде этого:

id  day duration    obs.period
A   1   0   60
A   2   0   60
A   3   0   60
A   4   0   60
A   5   12  60
A   6   1440    60
A   7   0   60
A   8   0   60
    .       
    .       
    .       
A   60  0   60
B   1   5   100
B   2   6   100
B   3   0   100
B   4   0   100
    .       
    .       
    .       
    .       
B   100 0   100

Есть идеи?

Ответы [ 4 ]

3 голосов
/ 25 сентября 2011

Вот один из подходов, использующий пакет plyr. Сначала создайте функцию, чтобы развернуть данные в соответствующее количество строк. Затем внесите в индекс этот новый data.frame с информацией о продолжительности из исходных данных. Наконец, вызовите эту функцию с ddply() и сгруппируйте переменную id.

require(plyr)
FUN <- function(x){
  dat <- data.frame(
    id = x[1,1]
    , day = seq_len(x[1,4])
    , duration = 0
    , obs.period = x[1,4]
    )

  dat[dat$id == x$id & dat$day == x$day, "duration"] <- x$duration
  return(dat)
}


ddply(data, "id", FUN)

    id day duration obs.period
1    A   1        0         60
2    A   2        0         60
3    A   3        0         60
4    A   4        0         60
5    A   5       12         60
6    A   6     1440         60
...
61   B   1        5        100
62   B   2        6        100
63   B   3        0        100
...
160  B 100        0        100
2 голосов
/ 25 сентября 2011

Создайте пустой фрейм данных с правильными столбцами индекса, но без столбцов значений, затем объедините его со своими данными и замените NA в столбцах значений нулями.

data<-data.frame(id=c("A","A","B","B"), day=c(5,6,1,2), duration=c(12,1440,5,6), obs.period=c(60, 60,100,100))
zilch=data.frame(id=rep(c("A","B"),each=60),day=1:60)
all=merge(zilch,data, all=T)
all[is.na(all$duration),"duration"]<-0
all[is.na(all$obs.period),"obs.period"]<-0
1 голос
/ 25 сентября 2011

Вот подход с plyr

fill1 <- function(df) {
  full_period <- 1:100
  to_fill <- setdiff(full_period, df$day)
  fill_id <- df[1,"id"]
  fill_dur <- 0
  fill_obs.p <- df[1,"obs.period"]
  rows_to_add <- data.frame(id=fill_id, day=to_fill, duration=fill_dur, obs.period=fill_obs.p)
  rbind(df,rows_to_add)
}
ddply(data, "id", fill1)

Результат не сортируется по идентификатору, продолжительности, однако.

1 голос
/ 25 сентября 2011

Сначала я создал бы фрейм данных, содержащий результаты.

ob.period <- with(data, tapply(obs.period, id, max))

n <- sum(ob.period)
result <- data.frame(id=rep(names(ob.period), ob.period),
                     day=unlist(lapply(ob.period, function(a) 1:a)),
                     duration=rep(0, n),
                     obs.period=rep(ob.period,ob.period))

Затем я вставил бы id и day вместе, используя match, чтобы найти соответствующие строки в больших данныхкадр и вставьте значения длительности.

idday.sm <- paste(data$id, data$day, sep=":")
idday.lg <- paste(result$id, result$day, sep=":")

result$duration[match(idday.sm, idday.lg)] <- data$duration
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...