R, dplyr: сборка наборов с одним ненулевым элементом на столбец - PullRequest
2 голосов
/ 09 апреля 2019

У меня есть массив данных с тысячами строк и несколькими десятками столбцов.Для данной строки R_0 я бы хотел итеративно найти дополнительную строку, добавить ее в набор, а затем найти строку, дополнительную к каждому элементу в наборе.Дополнительная строка определяется как:

  1. , если заданная строка имеет ненулевое значение для столбца, тогда дополнение должно иметь нулевое значение для этого столбца

Конечным результатом должен быть набор SKU, чья комбинация должна приводить к как можно меньшему количеству столбцов с нулевым значением.

Чтобы проиллюстрировать, вот игрушечный фрейм данных (код внизу):

  sku   p1_prop   p2_prop   p3_prop   p4_prop   p5_prop         rowTally
1   1   0         0         0         0.1634774 0                1
2   2   0.1617101 0.1700415 0         0         0                2
3   3   0         0         0         0         0.1385715        1
4   4   0         0         0.1785431 0         0.1399401        2
5   5   0.1682469 0         0         0         0                1
  totalDollarSales totalUnitSales dollarsPerRobot
1        386175.48       482131.9      0.80097474
2         13488.99       599605.9      0.02249643
3        382449.72       493592.0      0.77482973
4        869703.88       186299.0      4.66832335
5        340414.96       827390.6      0.41143200

Мне нужна функция, которая принимает первый SKU в наборе в качестве входных данных и находит все дополнительные элементы длянабор.

Например, мне нужна функция f:

f(df=A, sku=1, rowTallyThreshold)

Процесс итеративно добавляет SKU, который дополняет существующий набор.Если rowTallyThreshold = 3, то все строки, где rowTally<=3 могут быть добавлены к набору:

[1] -> [1, 2] -> [1, 2, 3]
[1] -> [1, 2] -> [1, 2, 4]

Если 'rowTallyThreshold` = 1, то все строки, где rowTally <= 1, или строки 1,3 и 5, потенциально могут быть добавлены к набору: </p>

[1] -> [1, 3] -> [1, 3, 5]

Результирующий вывод должен быть всеми возможными наборами.

Код для генерации MWE:

set.seed(1)
a = runif(n=25, min=0, max=0.18); a[a<0.13] = 0
A = as.data.frame(matrix(a, nrow=5, ncol=5, byrow = TRUE))
A$rowTally <- rowSums(A != 0); 
A$sku <- seq(from = 1, to = 5)
A$totalDollarSales <- runif(n=5, min=1*10^2, max=1*10^6)
A$totalUnitSales <- runif(n=5, min=1*10^2, max=1*10^6)
names(A) <- c("p1_prop", "p2_prop", "p3_prop", "p4_prop", "p5_prop", "rowTally", "sku", "totalDollarSales", "totalUnitSales")
A <- A[c("sku", "p1_prop", "p2_prop", "p3_prop", "p4_prop", "p5_prop", "rowTally", "totalDollarSales", "totalUnitSales")]
A$dollarsPerRobot <- A$totalDollarSales/A$totalUnitSales

1 Ответ

0 голосов
/ 09 апреля 2019

Как насчет этого:

library(tidyverse)

## y matches to x iff y is zero when x is not zero
is_match <- function(x, y) {
  all((x != 0 & y == 0) | (x == 0))
}

## Find complement skus of sku
find_matches <- function(df, sku, rowTallyThreshold, vars) {
  ## Vector of main sku
  main_sku <- as.numeric(df[df$sku == sku, vars])
  ## Potential candidates
  potential <- df %>%
    filter(rowTally <= rowTallyThreshold)
  ## Indices of matches
  match_idx <- apply(potential[vars], 1, function(y){is_match(main_sku, y)})
  ## Skus of matches
  potential$sku[match_idx]
}

find_matches(A, 1, 3, c("p1_prop", "p2_prop", "p3_prop", "p4_prop", "p5_prop"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...