首页 > 解决方案 > 在 R 中使用 combn 时保留非数字列

问题描述

我有一个类似于以下格式的数据框:

Doc Category val
A   aa        1
B   ab        6
C   ab        3
D   cc        6.....

我正在使用以下代码来识别 val 总和的所有组合,然后提取加起来为我已经识别的目标总和的行。

#all combinations
res <- Map(combn, list(val), seq_along(val), simplify = FALSE)
x=unlist(res, recursive = FALSE)
z=lapply(x, function(x) sum(x))

我的问题是确定在数据框中保留字符列的最佳方法,因为上面的代码只给出数值。我现在这样做的方式是基于 val 的映射,通常可以正常工作,但是,当存在重复值时,我可能会遇到问题。

例如,如果我的目标总和是 7,我最终希望输出看起来像这样(还有其他方法可以得到这个值,但现在只返回第一个实例有效):

Doc Category val
A   aa        1
B   ab        6

有没有更好的方法来映射到非数字列来实现这个输出?

标签: r

解决方案


此解决方案是否适合您:

df <- data.frame(Doc = LETTERS[1:7],
                 Category = c("aa","ab","ab","cc","ca","cb","bb"),
                 val = c(1,6,3, 6, 4, 5, 2), 
                 stringsAsFactors=FALSE)
df
#   Doc Category val
# 1   A       aa   1
# 2   B       ab   6
# 3   C       ab   3
# 4   D       cc   6
# 5   E       ca   4
# 6   F       cb   5
# 7   G       bb   2


target.sum=7

# create an "id" variable that is equal to the index of all rows
df$id <- seq_along(df$val)
id.res <- Map(combn, list(df$id), seq_along(df$id), simplify = FALSE)
x=unlist(id.res, recursive = FALSE)

#remove all elements in the list where the sum of 
# values in column val is not equal to target value
x.list <- lapply(x,FUN=function(x){ if(sum(df$val[x]) == target.sum ) df[x,] else NA})

#remove missing values
x.list <-x.list[!is.na(x.list)]

x.list
# [[1]]
#   Doc Category val id
# 1   A       aa   1  1
# 2   B       ab   6  2
# 
# [[2]]
#   Doc Category val id
# 1   A       aa   1  1
# 4   D       cc   6  4
# 
# [[3]]
#   Doc Category val id
# 3   C       ab   3  3
# 5   E       ca   4  5
# 
# [[4]]
#   Doc Category val id
# 6   F       cb   5  6
# 7   G       bb   2  7
# 
# [[5]]
#   Doc Category val id
# 1   A       aa   1  1
# 5   E       ca   4  5
# 7   G       bb   2  7

推荐阅读