Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
选择列总和等于R中固定值的行_R - Fatal编程技术网

选择列总和等于R中固定值的行

选择列总和等于R中固定值的行,r,R,我想得到一个(或全部)行的可能组合,其中数量列的和等于20 这里有一个例子: structure(list(id = 1:10, quantity = c(11L, 1L, 4L, 12L, 19L, 10L, 3L, 13L, 16L, 14L)), class ="data.frame", row.names = c(NA,-10L)) id quantity 1 11 2 1 3 4 4 12

我想得到一个(或全部)行的可能组合,其中数量列的和等于20

这里有一个例子:

structure(list(id = 1:10, quantity = c(11L, 1L, 4L, 12L, 19L, 10L, 3L, 13L, 16L, 14L)), class ="data.frame", row.names = c(NA,-10L))

id quantity
1   11          
2   1           
3   4           
4   12          
5   19          
6   10          
7   3           
8   13          
9   16          
10  14  
所需输出(一个可能的设置):


如果组合正常:

target <- 20
lapply(seq_len(sum(cumsum(sort(x$quantity)) <= target)), function(n) {
  y <- combn(x$quantity, n)
  y[,colSums(y) == target]
})
#[[1]]
#integer(0)
#
#[[2]]
#     [,1] [,2]
#[1,]    1    4
#[2,]   19   16
#
#[[3]]
#     [,1] [,2]
#[1,]    1    4
#[2,]    3    3
#[3,]   16   13
#
#[[4]]
#[1]  1  4 12  3

target这里是另一个基本的R解决方案,通过定义一个递归函数
子函数
(我想这会更快,因为它避免了检查所有的组合)


如果您只需要达到给定值的子集和中的一个,您可以尝试从package
adagio

library(adagio)
target <- 20
res <- df[subsetsum(df$quantity,target)$inds,]

您可以添加失败的内容吗?关于这些组合有哪些规则?没有固定的规则,我只需要满足sum(quantity)==20See的任何组合,以及如何获取相关ID?我已经进行了更新,返回了行-如最初所问。我喜欢您的解决方案,如何使它在满足求和条件的第一个组合处停止循环?我在if语句中添加了一个break指令,但它不起作用(我必须循环3000个产品,每个产品至少有长度为100的quantity数组)@Seif我认为您无法进入递归并提取第一个组合。相反,您可以使用package
adagio
中的函数
subsetsum
来创建它。查看我的更新。
target <- 20
lapply(seq_len(sum(cumsum(sort(x$quantity)) <= target)), function(n) {
  y <- combn(x$quantity, n)
  y[,colSums(y) == target]
})
#[[1]]
#integer(0)
#
#[[2]]
#     [,1] [,2]
#[1,]    1    4
#[2,]   19   16
#
#[[3]]
#     [,1] [,2]
#[1,]    1    4
#[2,]    3    3
#[3,]   16   13
#
#[[4]]
#[1]  1  4 12  3
lapply(seq_len(sum(cumsum(sort(x$quantity)) <= target)), function(n) {
  y <- combn(x$quantity, n)
  y <- y[,colSums(y) == target, drop = FALSE]
  if(length(y) > 0) {apply(y, 2, match, x$quantity)}
})
#[[1]]
#NULL
#
#[[2]]
#     [,1] [,2]
#[1,]    2    3
#[2,]    5    9
#
#[[3]]
#     [,1] [,2]
#[1,]    2    3
#[2,]    7    7
#[3,]    9    8
#
#[[4]]
#     [,1]
#[1,]    2
#[2,]    3
#[3,]    4
#[4,]    7
lapply(seq_len(sum(cumsum(sort(x$quantity)) <= target)), function(n) {
  y <- combn(x$quantity, n)
  y <- y[,colSums(y) == target, drop = FALSE]
  if(length(y) > 0) {apply(y, 2, function(i) {x[match(i, x$quantity),]})}
})
#[[1]]
#NULL
#
#[[2]]
#[[2]][[1]]
#  id quantity
#2  2        1
#5  5       19
#
#[[2]][[2]]
#  id quantity
#3  3        4
#9  9       16
#
#
#[[3]]
#[[3]][[1]]
#  id quantity
#2  2        1
#7  7        3
#9  9       16
#
#[[3]][[2]]
#  id quantity
#3  3        4
#7  7        3
#8  8       13
#
#
#[[4]]
#[[4]][[1]]
#  id quantity
#2  2        1
#3  3        4
#4  4       12
#7  7        3
x <- structure(list(id = 1:10, quantity = c(11L, 1L, 4L, 12L, 19L, 10L, 3L, 13L, 16L
  , 14L)), class ="data.frame", row.names = c(NA,-10L))
subsetSum <- function(v, target, r = c()) {
    if (sum(r) == target) {
        return(list(r))
    }
    unlist(lapply(seq_along(v), function(k) subsetSum(v[-(1:k)], target, c(r, v[k]))), recursive = FALSE)
}
target <- 20
lst <- subsetSum(setNames(df$quantity, seq(nrow(df))), target)
res <- Map(function(v) df[as.integer(names(v)), ], lst)
> res
[[1]]
  id quantity
2  2        1
3  3        4
4  4       12
7  7        3

[[2]]
  id quantity
2  2        1
5  5       19

[[3]]
  id quantity
2  2        1
7  7        3
9  9       16

[[4]]
  id quantity
3  3        4
7  7        3
8  8       13

[[5]]
  id quantity
3  3        4
9  9       16
library(adagio)
target <- 20
res <- df[subsetsum(df$quantity,target)$inds,]
> res
  id quantity
2  2        1
5  5       19