Как разделить набор данных по условиям в R - PullRequest
0 голосов
/ 31 января 2019

Я хотел бы получить общее правило, как бороться с этим подходом.У меня есть большие данные, но ниже приведен типичный пример:

set.seed(2019)

myFun <- function(n = 50) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
names = myFun()
group = round(runif(50, 0, 4))
condit = ifelse(round(runif(50, 0, 1.2)) > 0, "TRUE", "FALSE")
edf <- data.frame(names, group, condit, stringsAsFactors = F)
> head(edf)
       names group condit
1 NPWZX7229I     1  FALSE
2 FTANS2931N     0   TRUE
3 XUUGJ9010I     1  FALSE
4 THMIQ8703O     2   TRUE
5 NRLLS3573V     1   TRUE
6 LCETQ1320W     0  FALSE

Проблема состоит в том, чтобы разделить (кластеризовать) эти данные на N групп с ограничениями:

скажем N= 5,

каждая группа должна иметь, возможно, одинаковое количество значений ИСТИНА и ЛОЖЬ (как можно ближе к нему, если нет 50% -ной ставки)

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

Так, например, для N = 5 мы бы взяли вручную:

names   group   condit
wrd0        0     TRUE
wrd1        0     TRUE
wrd2        1     TRUE
wrd3        1    FALSE
wrd4        2    FALSE
wrd5        2    FALSE
wrd6        3     TRUE
wrd7        3    FALSE
wrd8        4    FALSE
wrd9        4     TRUE

Это идеально, но как автоматически повторить это длядругие группы?Это какая-то библиотека (наверняка), но я не знаю, что использовать.Кластер?Или, может быть, какой-то метод наименьших квадратов?Какую библиотеку использовать?Спасибо.

Предложение случайного разбиения имеет некоторый смысл и результат:

split(edf, sample(1:N, nrow(df), replace=T))

Но я знаю, что это могло бы быть лучше.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Ленивый путь

Вот tidyverse способ сделать это с помощью случайной выборки.

library(dplyr)
library(purrr)

edf %>%
  split(.$group) %>%
  map(~ sample_n(., size = 5, replace = T)) %>%
  bind_rows()

Пользовательский способ

Вот гибкий способ , который вы можете расширить с помощью собственных условий.Здесь я гарантировал, что все оригинальные образцы с менее чем 5 итерациями гарантированно будут включены.Как вы хотите справиться с асимметричной выборкой, зависит от вас.

library(dplyr)
library(purrr)

desired_sample_size = 5

conditional_sampling <- function(l){

    r = list(
      l %>% map(
                ~ sample_n(., 
                size = ifelse(nrow(.) < desired_sample_size, nrow(.), desired_sample_size), 
                replace = F)),
      l %>% map_if(~ desired_sample_size - nrow(.) > 0, 
                   ~ sample_n(., 
                              size = desired_sample_size - nrow(.), 
                              replace = T))
    )

    return(combine(r))
}

edf %>%
  split(.$group) %>%
  conditional_sampling() %>%
  bind_rows()
0 голосов
/ 01 февраля 2019

Наконец-то я нашел ответ.Это очень просто и, вероятно, дает наилучшую возможную посадку.Это итеративный материал.

devtools::install_github("m-Py/minDiff")

library(minDiff)

xdf <- create_groups(edf, criteria_scale = c("group"), 
                     criteria_nominal = c("condit"), sets_n = 5, repetitions = 5000)

Вы можете видеть, что он вполне там - в зависимости от того, насколько данные искажены или асимметричны, это дает худшее или лучшее чувство.

Просмотр по: xdf[order(xdf$newSet, xdf$condit, xdf$group),]

Уфф ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...