如何根据列值在R中创建组件(子集)数据帧?

时间:2011-06-08 11:38:58

标签: r split subset

我想根据一列中的值将数据帧拆分为多个组件数据帧。 在我的例子中,我想使用“cond”列中的值将dat分成dat.1,dat.2和dat.3。 是否有一个简单的命令可以实现这个目标?

dat
sub cond    trial   time01  time02
1   1   1   2774    8845
1   1   2   2697    9945
1   2   1   2219    9291
1   2   2   3886    7890
1   3   1   4011    9032
2   2   1   3478    8827
2   2   2   2263    8321
2   3   1   4312    7576
3   1   1   4219    7891
3   3   1   3992    6674


dat.1               
sub cond    trial   time01  time02
1   1   1   2774    8845
1   1   2   2697    9945
3   1   1   4219    7891    

dat.2               
sub cond    trial   time01  time02
2   2   1   3478    8827
2   2   2   2263    8321
1   2   1   2219    9291
1   2   2   3886    7890

dat.3               
sub cond    trial   time01  time02
1   3   1   4011    9032
2   3   1   4312    7576
3   3   1   3992    6674

也许是因为我是R新手,尽管浏览并尝试了几个类似论坛查询中提出的解决方案,但我仍然没有确定如何做到这一点。提前感谢您的回复。

dput()数据是:

structure(list(sub = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L
), cond = c(1L, 1L, 2L, 2L, 3L, 2L, 2L, 3L, 1L, 3L), trial = c(1L, 
2L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L), time01 = c(2774L, 2697L, 
2219L, 3886L, 4011L, 3478L, 2263L, 4312L, 4219L, 3992L), time02 = c(8845L, 
9945L, 9291L, 7890L, 9032L, 8827L, 8321L, 7576L, 7891L, 6674L
)), .Names = c("sub", "cond", "trial", "time01", "time02"), class = "data.frame", row.names = c(NA, 
-10L))

5 个答案:

答案 0 :(得分:9)

我认为最简单的方法是通过split

split(dat, dat$cond)

但请注意,split会返回data.frames的列表。

要从列表中获取单个data.frames,您可以使用循环创建单个对象(隐含在lapply语句中),如下所示:

tmp <- split(dat, dat$cond)
lapply(1:length(tmp), function(x) assign(paste("dat.", x, sep = ""), tmp[[x]], envir = .GlobalEnv))

但是,使用列表可能更多R ish,从长远来看会更有用。

感谢Gavin发布数据!

答案 1 :(得分:7)

有什么不满意的吗

split(dat, dat$cond)

? 你确实有R和拆分作为标签......

答案 2 :(得分:6)

是的,split()。例如,如果您的数据位于dat,则:

with(dat, split(dat, cond))

返回一个列表,其组件是您想要的数据框:

R> with(dat, split(dat, cond))
$`1`
  sub cond trial time01 time02
1   1    1     1   2774   8845
2   1    1     2   2697   9945
9   3    1     1   4219   7891

$`2`
  sub cond trial time01 time02
3   1    2     1   2219   9291
4   1    2     2   3886   7890
6   2    2     1   3478   8827
7   2    2     2   2263   8321

$`3`
   sub cond trial time01 time02
5    1    3     1   4011   9032
8    2    3     1   4312   7576
10   3    3     1   3992   6674

答案 3 :(得分:4)

为了完整起见,这是使用plyr包进行此操作的方法。

require(plyr)

> dlply( dat, .(cond))
$`1`
  sub cond trial time01 time02
1   1    1     1   2774   8845
2   1    1     2   2697   9945
9   3    1     1   4219   7891

$`2`
  sub cond trial time01 time02
3   1    2     1   2219   9291
4   1    2     2   3886   7890
6   2    2     1   3478   8827
7   2    2     2   2263   8321

$`3`
   sub cond trial time01 time02
5    1    3     1   4011   9032
8    2    3     1   4312   7576
10   3    3     1   3992   6674

attr(,"class")
[1] "split" "list" 

注意语法的简单性,因为你只提到dat一次。

答案 4 :(得分:0)

ucond <- unique(dat$cond)
dat_by_cond <- lapply(lapply(ucond, "==", dat$cond), subset, x=dat)
names(dat_by_cond) <- paste("dat",ucond,sep=".")