假设我有三个人A
,B
和C
的数据,并且每个人都有两个特征,"学年和#34;({ {1}})和"兄弟姐妹的数量"(YS
)。因此,数据集NS
如下所示:
X
现在,我必须根据id <- c("A", "B", "C")
YS <- c(6, 9, 8)
NS <-c(1, 0, 3)
X <- data.frame(id, YS, NS)
,A
和B
的所有可能组合重新整理数据集,这意味着将有2 ^ 3-1组合。更准确地说,这些组合包括:C
,A
,B
,C
,AB
,AC
,BC
和ABC
组合(即2 ^ 3-1组合)。除了组合个体之外,我还必须计算每个组合的每个特征的值。例如,组合null
的{{1}}和YS
值为15和1.另一个例子,NS
和AB
的值为组合YS
分别为23和4。
我理解使用代码NS
生成可能的组合,但我不知道如何同时组合特征值。有人可以帮忙吗?感谢。
答案 0 :(得分:3)
不是很漂亮或像R一样,但它有效。它包括根据问题设置的NULL。
# function to create the combinations and sum the elements
reorgCombs <- function(data) {
ids <- rownames(data)
newdata <- data.frame(comb = c("NULL", id), YS = c(0, data[, "YS"]),
NS = c(0, data[, "NS"]), row.names = NULL)
for (i in 2:nrow(data)) {
theseCombs <- t(combn(ids, i))
newdata <- rbind(newdata,
data.frame(comb = apply(theseCombs, 1, paste0, collapse=""),
YS = apply(theseCombs, 1, function(x) sum(data[x, "YS"])),
NS = apply(theseCombs, 1, function(x) sum(data[x, "NS"]))))
}
newdata
}
# make this a numeric matrix with named dimensions
# the names will be used for lookup
X2 <- cbind(YS, NS)
rownames(X2) <- id
reorgCombs(X)
## comb YS NS
## 1 NULL 0 0
## 1 A 6 1
## 2 B 9 0
## 3 C 8 3
## 4 AB 15 1
## 5 AC 14 4
## 6 BC 17 3
## 7 ABC 23 4
使用新基准编辑:
也许是因为查询表,即使循环它的相对较快 - 但以马修的解决方案为主:
## Unit: relative
## expr min lq mean median uq max neval
## jota 4.479829 4.408874 4.304705 4.455843 4.335172 3.730202 100
## pierre 11.606636 11.623717 12.743089 12.078027 11.761123 19.271072 100
## ken 3.034247 3.015091 2.978181 3.040916 2.914744 2.755357 100
## matthew 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 100
## frank 4.572867 4.615341 4.590244 4.719418 4.516317 3.978101 100
答案 1 :(得分:3)
这是combn
all_combn <- function(x, ...)
unlist(sapply(seq_along(x), combn, x=x, ...))
data.frame(
id=all_combn(id, paste, collapse=''),
YS=all_combn(YS, sum),
NS=all_combn(NS, sum)
)
# id YS NS
# 1 A 6 1
# 2 B 9 0
# 3 C 8 3
# 4 AB 15 1
# 5 AC 14 4
# 6 BC 17 3
# 7 ABC 23 4
答案 2 :(得分:1)
这是在基地R中进行此操作的一种方法。首先,确定组合:
n = nrow(X)
combos = do.call(rbind, lapply(seq(n), function(x){
r = combn(n, x)
data.frame( r = c(r), g = paste(x, c(col(r)), sep=".") )
}))
然后,为每个组合选择X
行:
Xc = X[combos$r,]
Xc$id = as.character(Xc$id)
Xc$g = ave(Xc$id, combos$g, FUN = function(x) paste0(x,collapse=''))
最后,每个组合的聚合:
aggregate(cbind(YS,NS)~g, Xc, sum)
# g YS NS
# 1 A 6 1
# 2 AB 15 1
# 3 ABC 23 4
# 4 AC 14 4
# 5 B 9 0
# 6 BC 17 3
# 7 C 8 3
您以这种方式错过了空集,但如果需要,rbind
就足够了。
答案 3 :(得分:0)
看起来很多,但我碰巧使用splitstackshape
作为另一个答案,并在这里看到了应用程序的可能性。第一个电话是lst1 <- do.call(c, "all combinations")
。这就像你提到的所有可能性一样创建了列表。如果您愿意,可以稍后添加NULL
之类的边缘案例。我们从lst1
创建一个数据框来组织信息。函数cSplit
将df
重新整形为长整数。我们合并以添加数字值。最后,使用dplyr
我们按照我们创建的索引列进行分组,将所有因素转换为integer
类型,然后找到总和:
library(dplyr)
library(splitstackshape)
lst1 <- do.call(c, lapply(1:3, function(i) combn(id, i, simplify=F)))
df <- data.frame(indx=seq_along(lst1), combs=sapply(lst1, toString))
df.long <- cSplit(df, 'combs', direction="long")
m <- merge(X, df.long, by.x='id', by.y='combs')
m %>% group_by(indx) %>%
mutate_each(funs(as.integer(as.character(.))), -id) %>%
summarise(id=toString(id), YS=sum(YS), NS=sum(NS))
# Source: local data frame [7 x 4]
#
# indx id YS NS
# (int) (chr) (int) (int)
# 1 1 A 6 1
# 2 2 B 9 0
# 3 3 C 8 3
# 4 4 A, B 15 1
# 5 5 A, C 14 4
# 6 6 B, C 17 3
# 7 7 A, B, C 23 4