[英]How to divide dataset by conditions in R
我想獲得一些如何處理這種方法的一般規則。 我有大數據,但以下是其中的代表性示例:
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
每個組都需要具有相同數量的TRUE和FALSE值(在沒有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))
但是我知道這可能更合適。
最后,我找到了答案。 這非常簡單,可能會提供最佳的擬合度。 這是迭代的東西。
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),]
ff ...
懶惰的方式
這是通過隨機采樣來完成的一種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()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.