基于主题数量组合的数据转换

时间:2012-10-24 16:02:38

标签: r

我有一个大数据集,并希望根据主题数量的组合对其进行转换。以下是简化的示例数据框:

data <- read.table(textConnection("
group subject status v1 v2
    1       1      1  4 21
    1       2      0  7 10
    1       3      1  3  9
2       1      0  8 75
2       2      1  5  7
2       3      1  2 11
2       4      1  6  1
3       1      1  9 37"), header = TRUE) 

在第一组中,有三个受试者,其中第一个和第三个具有状态= 1.两个可能的受试者的组合,状态= 1来自三个受试者是{(1,2),(1,3), (2,3)}。转换后,第一组的新数据如下所示:

newgroup newsubject newstatus newv1 newv2
       1          1         0    11    31
       1          2         1     7    30
       1          3         0    10    19

其中只有第二个新主题在newstatus中取1,因为它是从第一个和第三个主题转换而来的,它们在原始数据中都处于1状态。 newv1和newv2是从v1v2的总和转换而来的:v1_1 + v1_2 = 4 + 7 = 11, v1_1 + v1_3 = 4 + 3 = 7, v1_2 + v1_3 = 7 + 3 = 10 ……

在第四组中,有四个受试者,其中第二到第四个具有状态= 1.来自四个受试者的三个可能受试者status = 1的组合是{(1,2,3),(1 ,2,4),(1,3,4),(2,3,4)}。转换后,第二组的新数据如下所示:

newgroup newsubject newstatus newv1 newv2
       2          1         0    15    93
       2          2         0    19    83
       2          3         0    16    87
       2          4         1    13    19

这三组的新数据如下所示:

data <- read.table(textConnection("
newgroup newsubject newstatus newv1 newv2
       1          1         0    11    31
       1          2         1     7    30
       1          3         0    10    19
       2          1         0    15    93
       2          2         0    19    83
       2          3         0    16    87
       2          4         1    13    19
       3          1         1     9    37"), header = TRUE) 

有人能提供一些帮助吗?

1 个答案:

答案 0 :(得分:2)

这将完成这项工作:

# first define the function we will apply to each group
f <- function(group) {
    if (nrow(group) == 1 | sum(group$status) == 0) 
        group
    else 
        with(group, {
                v1 = combn(v1, sum(status), sum)
                v2 = combn(v2, sum(status), sum)
                status = ifelse(combn(status, sum(status), sum) == sum(status), 1, 0)
                subject = seq_along(v1)
                group = rep(group, length.out=length(v1))
                data.frame(group, subject, status, v1, v2)
        })
}

# apply f using by and collapse the results into a data.frame
do.call(rbind, by(data, INDICES=data$group, f))

#     group subject status v1 v2
# 1.1     1       1      0 11 31
# 1.2     1       2      1  7 30
# 1.3     1       3      0 10 19
# 2.4     2       1      0 15 93
# 2.5     2       2      0 19 83
# 2.6     2       3      0 16 87
# 2.7     2       4      1 13 19
# 3       3       1      1  9 37