2

我有一个data.frame我想分成一个列表。

我有:

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

但是,唉,我不知道该怎么做。

4

3 回答 3

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
于 2013-04-04T22:05:16.277 回答
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. +组合很难lapplyhead
于 2013-04-04T21:50:28.300 回答
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
于 2013-04-04T23:05:56.580 回答