2013-04-04 2 views
2

У меня есть data.frame, который я хочу разбить на их список.Значения спредов по NA

у меня есть:

data.frame(value=c(1:4,NA,11:12,NA,21:23,NA), 
      key=as.factor(c(NA,NA,NA,NA,"a",NA,NA,"b",NA,NA,NA,"c"))) 
    value key 
1  1 <NA> 
2  2 <NA> 
3  3 <NA> 
4  4 <NA> 
5  NA a 
6  11 <NA> 
7  12 <NA> 
8  NA b 
9  21 <NA> 
10 22 <NA> 
11 23 <NA> 
12 NA c 

Я хочу:

list(a=data.frame(value=1:4), 
    b=data.frame(value=11:12), 
    c=data.frame(value=21:23)) 
$a 
    value 
1  1 
2  2 
3  3 
4  4 

$b 
    value 
1 11 
2 12 

$c 
    value 
1 21 
2 22 
3 23 

я должен быть в состоянии использовать split, чтобы получить то, что я хочу, если я мог бы преобразовать key столбец

[1] a a a a a b b b c c c c 
Levels: a b c 

но, увы, я не знаю, как это сделать.

ответ

3

Это даст вам свою квартиру вектор который вы можете split если вам нравится:

library(zoo) 
na.locf(f$key, fromLast = TRUE) 

[1] a a a a a b b b c c c c 
Levels: a b c 
2

Вот мое решение:

> f <- data.frame(value=c(1:4,NA,11:12,NA,21:23,NA), 
        key=as.factor(c(NA,NA,NA,NA,"a",NA,NA,"b",NA,NA,NA,"c"))) 
> keys <- f$key 
> good <- !is.na(keys) 
> f$key <- NULL 
> l <- split(f,head(cumsum(c(0,good)),-1)) 
> names(l) <- keys[good] 
> lapply(l, function(df) head(df,-1)) 
$a 
    value 
1  1 
2  2 
3  3 
4  4 

$b 
    value 
6 11 
7 12 

$c 
    value 
9  21 
10 22 
11 23 

есть лучший способ?

В частности, то, что мне не нравится это

  1. сочетание head + cumsum + c некрасиво
  2. сочетание lapply + head некрасиво
1

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

> dat <- data.frame(value=c(1:4,NA,11:12,NA,21:23,NA),key=as.factor(c(NA,NA,NA,NA,"a",NA,NA,"b",NA,NA,NA,"c"))) 
> 
> labels <- which(!is.na(dat$key)) 
> j <- 1 
> for(i in labels){ 
+ dat$key[j:i] <- dat$key[i] 
+ j = i + 1 
+ } 
> 
> split(dat$value[!is.na(dat$value)],as.factor(dat$key[-labels])) 
$a 
[1] 1 2 3 4 

$b 
[1] 11 12 

$c 
[1] 21 22 23 
Смежные вопросы