从多个测试中分组观察结果

时间:2013-08-20 22:00:14

标签: r plyr

我已经在这方面工作了很长时间才能看到a)可能有一种简单的方法可以做到这一点,并且b)在我做之前可能会看到一双新鲜的眼睛。所以这里...... ..

进行了两次或多次测试以将项目分类为两个或更多类别。我们假设使用分类器组合可以得到更可靠的测量结果。为了测试这一点,我们需要了解预测如何相互协调,而不是仅仅汇总各个测试的结果。该分析的第一步是通过将测试结果分组到观察中来同时模拟来自所有测试的测量结果。

set.seed(103)
test1 <- data.frame(trueClass=rep(c('A','B','C'), times=c(2,3,4)), score=rpois(9,10))
test2 <- data.frame(trueClass=rep(c('A','B','C'), times=c(3,3,3)), score=rpois(9,5))
test3 <- data.frame(trueClass=rep(c('A','B','C'), times=c(4,2,3)), score=rpois(9,2))

all.data <- list(test1=test1, test2=test2, test3=test3)

我们将观察定义为包含来自同一score的每个测试中的一个trueClass的有序三元组。理想情况下,最终我们会有一个看起来像

的整洁data.frame
>observation.df
  test1 test2 test3 trueClass
1    11     6     2         A
2    16     4     4         A
3     6     9     2         B
4   ...

难点在于观察数量受到测试中类别的最低表示数量的限制。在这种情况下,最小值是

mins <- c(A=2, B=2, C=3)

因此,我想使用trueClass = A对每个测试的2个测试结果进行抽样,使用trueClass = B对2进行抽样,将trueClass = C抽样3,并将其存储在observation.df中。< / p>

显然,创建观察的函数需要从all.data学习测试的名称和类。

test.names <- names(all.data)
class.names <- unique(as.vector(sapply(all.data, function(i) i$trueClass)))

获取要抽样的每个班级的数量:

library(plyr)
count.table <- laply(all.data, function(i) table(i$trueClass))
mins <- apply(count.table, 2, min)

在我看来应该有一个相当直接的方式从这里(可能使用byplyr函数),但我没有成功除了使问题复杂化

2 个答案:

答案 0 :(得分:2)

你正在寻找这个吗? (这是一种快速而肮脏的方法)

  library(plyr)
  set.seed(103)
  test1 <- data.frame(trueClass=rep(c('A','B','C'), times=c(2,3,4)), score=rpois(9,10))
  test2 <- data.frame(trueClass=rep(c('A','B','C'), times=c(3,3,3)), score=rpois(9,5))
  test3 <- data.frame(trueClass=rep(c('A','B','C'), times=c(4,2,3)), score=rpois(9,2))
  all.data <- list(test1, test2, test3)
  num<-list(1,2,3)
  kk<-Map(function(x) ddply(all.data[[x]],.(trueClass),summarize,sam1=unique(ifelse(trueClass %in% c("A","B"),sample(score,2),sample(score,3)))),num)



 > kk
[[1]]
  trueClass sam1
1         A   10
2         A    7
3         B    8
4         B    5
5         C   12
6         C    7
7         C    6

[[2]]
  trueClass sam1
1         A    5
2         A    8
3         B    4
4         B    9
5         C    8
6         C    3

[[3]]
  trueClass sam1
1         A    0
2         A    2
3         B    4
4         B    2
5         C    3
6         C    0



kkk<-ldply(kk)
kkk$test<-with(kkk,rep(c("test1","test2","test3"),c(nrow(kk[[1]]),nrow(kk[[2]]),nrow(kk[[3]]))))
> kkk
   trueClass sam1  test
1          A    7 test1
2          A   10 test1
3          B    8 test1
4          B    5 test1
5          C   12 test1
6          C    8 test1
7          C    7 test1
8          A    8 test2
9          A    5 test2
10         B    9 test2
11         B   12 test2
12         C    8 test2
13         C    3 test2
14         A    2 test3
15         A    5 test3
16         B    2 test3
17         B    4 test3
18         C    3 test3
19         C    0 test3

您可以使用reshape来获得所需内容。

答案 1 :(得分:2)

可能是一个相当复杂的答案,但它完成了工作。

cutlist <- lapply(all.data,
  function(x)
  do.call(rbind,
    sapply(names(mins), function(y) {
       subs <- x[x$trueClass==y,]
       subs[sample(1:nrow(subs),mins[y]),]
       },
    simplify=FALSE
    )
  )
)

cbind(cutlist[[1]]["trueClass"] , sapply(cutlist,"[[","score",simplify=TRUE))

结果:

    trueClass  1 2 3
A.1         A  7 8 2
A.2         A 10 5 5
B.5         B  8 4 4
B.4         B  4 9 2
C.7         C  6 3 3
C.9         C  7 8 0
C.8         C  8 8 3