Я пытаюсь получить образец из большого набора данных из трех столбцов. Образец должен соответствовать следующим критериям:Образец строки с ограниченными комбинациями
- Получить определенное количество строк каждого значения группы. Существует три групповых значения (1,2-3,4-5)
Используйте только определенное количество символов в строках letter1 и letter2. То есть: Условие относительно ограниченное количество писем проверяется следующим образом: (где s является dataframe раствор)
NROW(unique(append(s$letter1,s$letter2))) 4
Минимальный набор данных выглядит следующим образом:
>df
letter1 letter2 value
a b 1
a c 1
a d 3
b a 1
c b 1
c d 2
c e 4
d a 5
d e 1
d c 2
(Значение в lettter1 всегда отличается от значения в letter2).
Например, из примера набора данных я хочу образец, который включает в себя 1 строку значения 4-5, 1 строку значения 2-3 и 4 строки значения 1. Я хочу, чтобы на панели отображались только комбинации из 4 разных букв первые две колонки. В этом случае есть два возможных решения (и их перестановки), как с использованием букв a, b, c, d. Мне просто нужно получить одну (или перестановку), мне все равно.
>s1
letter1 letter2 value
a b 1
a c 1
a d 3
b a 1
c b 1
d a 5
>s2
letter1 letter2 value
a b 1
a c 1
b a 1
c b 1
c d 2
d a 5
Раствор для минимальной dataframe но не реально (больше) один
Я решил эту проблему для минимальной dataframe выше, но, к сожалению, слишком медленно для реального dataframe мне нужно обработать. Эти решения состоят из:
- Получение возможной комбинации желаемого количества уникальных букв (u = 4 в этом примере).
- Для каждой из этих комбинаций перестановки в наборах из двух (как они могут появляться в столбцах letter1 и letter2 в кадре данных).
- Получите строки в фрейме данных перестановок (l), которые также находятся в исходном (df), используя semi_join().
- Получите строки, принадлежащие каждой группе значений, и проверьте, достаточно ли их для удовлетворения требуемого количества строк для каждой группы.
- Если это так, и если для удовлетворения этого требования требуется больше, выберите произвольно между ними.
Функция ниже возвращает первую группу букв u, с комбинацией которых мы можем встретить требуемое количество строк в каждой группе, заданной группами. группы - это числовой вектор трех разрезов, которые представляют количество строк для каждой группы значений. группы [1] - количество требуемых строк со значением 1, группы [2] число требуемых строк со значениями 2-3 и группы [3] число требуемых строк со значениями 4-5.
library(trotter)
library(gtools)
library(dplyr)
obtainValues <- function (df,u,groups){
# Get unique letter values in the dataframe
lett <- unique(append(df$letter1,df$letter2))
# All possible combinations of letters in lett in groups of u letters
letters <- cpv(u,lett)
# Iterate over any possible group of 4 letters
for(i in 1:length(letters)){
l <- as.character(letters[i])
l <- as.data.frame(permutations(u,2,l),stringAsFactors=FALSE)
names(l) <- c("letter1","letter2")
dc <- semi_join(df,l,by = c("letter1", "letter2"))
#Groups of values of each type with the current letters
g1 <- dc[dc$value == 1,]
g2 <- dc[dc$value > 1 & dc$value < 4,]
g3 <- dc[dc$value > 3,]
if(NROW(g1) >= groups[1] & NROW(g2) >= groups[2] & NROW(g3) >= groups[2]){
# I do not want more rows of each type than the requested ones
g1 <- g1[sample(nrow(g1),groups[1]),]
g2 <- g2[sample(nrow(g2),groups[2]),]
g3 <- g3[sample(nrow(g3),groups[3]),]
# Join chosen rows in a dataframe
g <- rbind(g1,g2)
g <- rbind(g,g3)
return(g)
}
}
}
df <- data.frame(c("a","a","a","b","c","c","c","d","d","d"),c("b","c","d","a","b","d","e","a","e","c"), c(1,1,3,1,1,2,4,5,1,2), stringsAsFactors=FALSE)
names(df) <- c("letter1","letter2","value")
groups <- c(4,1,1)
u <- 4
obtainValues(df,u,tieGroups)
Проблема
Реальный dataframe слишком велик, и это не представляется возможным перебирать 1: длина (буквы).Можно разделить длину и сделать цикл for для разных групп значений в буквах за раз, но это очень медленно, так как мой dataframe довольно большой. Есть ли другое решение? Любой способ избежать цикла for? Или способ каким-то образом адаптировать мое решение к более крупным данным?
Могут быть только две возможности относительно группы значений 1 (я возьму ваше слово для этого), но есть 3 со значениями 2 и 2 со значением 3, поэтому есть (по крайней мере) 12 возможных результатов. –
@ 42- Извините, но я не понимаю. Используя только комбинации из 4 разных букв в первых двух столбцах, я не вижу более двух решений. –