There is a dataframe with data

dat cluster1 cluster2 cluster3 cluster4 cluster5 target.label 1 24 5 18 21 16 1 2 2 15 12 7 22 1 3 13 13 16 29 24 0 4 23 28 22 10 4 1 5 6 12 20 25 11 0 6 25 17 14 24 25 1 7 30 27 2 4 14 0 8 11 2 21 6 9 0 9 20 20 29 17 10 1 10 7 30 25 11 15 0 11 19 8 15 8 18 0 12 3 18 1 16 26 0 13 17 9 23 14 8 0 14 5 6 5 22 19 0 15 9 19 9 12 20 1 16 21 3 3 13 23 1 17 10 16 4 26 2 1 18 18 4 28 3 6 0 19 28 24 7 20 12 0 20 8 11 11 23 7 1 21 15 14 6 27 27 0 22 26 29 26 28 29 1 23 16 1 10 2 17 0 24 1 7 17 15 21 0 25 27 23 30 5 13 1 26 12 22 19 9 30 1 

In the data we have columns with clusters with a range from 1 to 30 each and the last column with a target that can have values ​​of 0 or 1

you need to find such lines that repeat at least 10 times in the entire sample and in each of the identical groups found that were repeated, the number "1" in the target.label must exceed 70% relative to "0"

like so

 cluster1 cluster2 cluster3 cluster4 cluster5 target.label 1 24 5 18 21 16 1 2 24 5 18 21 16 1 3 24 5 18 21 16 0 4 24 5 18 21 16 1 5 24 5 18 21 16 1 6 24 5 18 21 16 1 7 24 5 18 21 16 1 8 24 5 18 21 16 0 9 24 5 18 21 16 1 10 24 5 18 21 16 1 ..... ..... ...... 

Here the identical lines found are more than zeros ...

how this can be implemented, and it is important that as quickly as possible, as there will be a lot of such calculations

  • Check out the partykit package. - Artem Klevtsov
  • Can you show the code? but I looked at it, but I understood little - mr.T

2 answers 2

Here is a more elegant solution. And most importantly, only the dplyr and tidyr packages dplyr tidyr , which probably provides the maximum execution speed. All further comments in the code.

 library(tidyverse) # это удобный способ подгрузить сразу весь мир пакетов Hadley # создаем данные, подходящие по описанию - миллион наблюдений df_raw <- data_frame(cluster1 = sample(0:9,1e6,replace = T), cluster2 = sample(0:9,1e6,replace = T), cluster3 = sample(0:9,1e6,replace = T), cluster4 = sample(0:9,1e6,replace = T), cluster5 = sample(0:9,1e6,replace = T), target.label = sample(0:1,1e6,replace = T)) # создаем переменную со всей последовательностью df <- df_raw %>% unite(seq, cluster1:cluster5, sep = '-', remove = F) df_count <- df %>% select(seq,target.label) %>% group_by(seq) %>% # группируем по последовательностям summarise(size = n(), # размер группы (сколько раз встречается последовательность) target = sum(target.label), # просто суммируем share = target/size) %>% # считаем долю единиц ungroup() # отбираем последовательности, которые удовлетворяют заданному условию df_cond <- df_count %>% filter(size >= 10, share >=.7) # если надо, можно слить результат с исходной таблицей, чтобы знать, какие конкретно # наблюдения удовлетворяют условию df_back <- left_join(df, df_cond %>% transmute(seq, cond = 'yes'), by = 'seq') %>% replace_na(replace = list(cond = 'no')) # (UPD) заменить пустые значения на 'no' 
  • thank you, kind people :) everything turned out - mr.T

Below is a code fragment that solves the problem. Verified

 # основная идея на основании заданного дата фрэйма создать новый в котором посчитано # для уникального сочетания строк по полям cluster1, cluster2, ... # количество с 0-ми, 1-ми и общее количество строк # исключаем строки не удовлетворяющие требуемым условиям и в дальнейшем новый дата фрэйм # используем как эталон для выборки из заданного дата фрэйма library(dplyr) # файл с данными data.file <- "/home/UserName/Документы/questions_586979/dtfrm.csv" Mx.Sz <- 2 #10 - переменная для граничного условия "нужно найти такие строчки которые повторяются не менее 10 раз в всей выборке" # для прогона тестового примера определяем 2 Mx.Prcnt <- 60 # переменная для граничного условия "в каждой из найденных одинаковых групок которые повторялись, количество "1" # в target.label должно превышать 70% по отношению к "0" # для прогона тестового примера определяем 60% # открываем файл с данными df <- read.csv2(data.file) # создаем два дополнительных столбца, по количеству возможныйх значений в target.label # trgt.lbl.0 и заполняем 1 если значение target.label = 0 # trgt.lbl.1 и заполняем 1 если значение target.label = 1 df.tmp1 <- mutate(df, cluster1, cluster2, cluster3, cluster4, cluster5, trgt.lbl.0 = ifelse(target.label == 0, 1, 0), trgt.lbl.1 = ifelse(target.label == 1, 1, 0)) # производим группировку по полям cluster1, cluster2,... df.tmp2 <- group_by(df.tmp1, cluster1, cluster2, cluster3, cluster4, cluster5) # суммируем по столбцам trgt.lbl.0, trgt.lbl.1 для определения количества 0 и 1 в строке # далее используем для определения % соотношения количества строк с 1 к общему количеству строк # для уникального сочетания cluster1, cluster2 ... # определяем количество строк с уникальным сочетанием значений по полям cluster1, cluster2 ... # далее количество строк используем для исключения строк не удовлетворяющий условию Mx.Sz df.tmp3 <- summarise(df.tmp2, sm.0 = sum(trgt.lbl.0), sm.1 = sum(trgt.lbl.1), all.rc = n()) # создаем поле sm.1.prcnt - значение которого показывает количество % строк с 1-ми к общему количеству # для уникального сочетания cluster1, cluster2 ... df.tmp4 <- mutate(df.tmp3, sm.1.prcnt = sm.1*100/all.rc) # исключаем строки не удовлетворяющих нашим граничным условиям # по общему количеству строк и процентному соотношению строк с 1-ми # в результате получили дата фрэйм содержащий необходимые нам строки df.tmp5 <- filter(df.tmp4, all.rc >= Mx.Sz & sm.1.prcnt >= Mx.Prcnt) # в цикле на основании строк, удовлетворяющих требованиям, выбираем строки из исходного дата фрэйма # с последующей записью в файл for (i in 1:nrow(df.tmp5)) { # результирующий дата фрэйм df.tmp6 <- filter(df, as.integer(cluster1) == as.integer(df.tmp5[i, 1]) & as.integer(cluster2) == as.integer(df.tmp5[i, 2]) & as.integer(cluster3) == as.integer(df.tmp5[i, 3]) & as.integer(cluster4) == as.integer(df.tmp5[i, 4]) & as.integer(cluster5) == as.integer(df.tmp5[i, 5])) # имя результирующего дата фрэйма nm.rslt <- paste0("nm.rslt.",i, ".csv") # записываем результат write.csv(df.tmp6, file = nm.rslt, row.names=FALSE) }