在R中使用combn时保留非数字列

时间:2018-05-16 20:00:37

标签: r

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

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

有没有更好的方法映射到非数字列以实现此输出?

1 个答案:

答案 0 :(得分:0)

此解决方案是否适合您:

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