#r #dplyr
#r #dplyr
Вопрос:
У меня есть dataframe значений с тысячами строк и парой десятков столбцов. Для данной строки, R_0
я хотел бы итеративно найти дополнительную строку, добавить ее в набор, затем найти строку, дополнительную к каждому элементу в наборе. Дополнительная строка определяется как:
- если данная строка имеет ненулевое значение для столбца, то дополнение должно иметь нулевое значение для этого столбца
Конечным результатом должен быть набор 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
Мне нужна функция, которая принимает первый артикул в наборе в качестве входных данных и находит все дополнительные элементы к набору.
Например, мне нужна функция f
:
f(df=A, sku=1, rowTallyThreshold)
Процесс итеративно добавляет артикул, который дополняет существующий набор. Если rowTallyThreshold
= 3, то все строки, где rowTally<=3
могут быть добавлены к набору:
[1] -> [1, 2] -> [1, 2, 3]
[1] -> [1, 2] -> [1, 2, 4]
Если ‘rowTallyThreshold` = 1, то все строки, где rowTally<=1, или строки 1, 3 и 5, потенциально могут быть добавлены в набор:
[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. Я не понимаю, что
rowTallyThreshold
означает. Почему при значении 3 можно добавлять только строки <=3 или строки 1, 3 и 5 при значении 1? Я предполагаю, что в этом есть логика, но я еще не догадался об этом.2. Для целей этого конкретного вопроса вас интересуют какие-либо столбцы, кроме
p1_prop p2_prop p3_prop p4_prop p5_prop rowTally
?3. @JonSpring
rowTallyThreshold
— это то, с чем следует сравниватьrowTally
столбец во фрейме данных. ЕслиrowTally
<=rowTallyThreshold
, то эта строка является жизнеспособным кандидатом для добавления в набор, предполагая, что она имеет неперекрывающиеся значения для столбцов4. @JonSpring для этого вопроса меня интересуют только эти столбцы
Ответ №1:
Как насчет этого:
library(tidyverse)
## y matches to x iff y is zero when x is not zero
is_match <- function(x, y) {
all((x != 0 amp; 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"))
Комментарии:
1. Спасибо, это приближает меня. Фактический результат должен быть:
[2,3]; [3]; [4]
поскольку существует 3 возможных комбинации артикулов / строк, включая артикул / строку 1. Результатом должен быть фрейм данных2. Извините, что ваша запись не ясна. Не могли бы вы уточнить, чего вы хотите, пожалуйста? Моя функция возвращает артикулы, как вы задали в вопросе.