Вложенный dplyr L oop в r - PullRequest
2 голосов
/ 17 июня 2020

Я пытаюсь выполнить вложенный l oop в r, чтобы выполнить сложную случайную выборку. Краткое изложение того, что у меня есть и чего я пытаюсь достичь sh.

У меня есть набор данных (пример кода ниже) с 3 переменными. Каждая переменная имеет значение 1 или 0. Я хочу выбрать разное количество раз для каждой переменной, но только для значений «1».

Так, например, для столбца «A» я хочу образец 1 случайная уникальная строка со значением '1' в столбце.

Я новичок в циклах, а вложенный l oop меня застрял.

edit: исправлен образец dataframe.

library(tidyverse)

###create sample data set

id<-c('l','m','n','o','p')

A<-c(0,1,1,1,1)

B<-c(1,1,1,0,1)

C<-c(1,1,1,0,1)

RISK_LEVEL<-c('3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated')

data<-as.data.frame(id, A, B, C, RISK_LEVEL)


#list with number of samples I want to take from each column
high_count<-c(1,3,2)

#list of columns I want to sample from
groups<-c('A','B','C')

#create blank dataframe to house output
high_samp<-list(matrix(,nrow=5,ncol=5))

###nested loop
for (j in 1:length(groups)) {

  for (i in 1:length(high_count)) {

high_samp[[i]]<-data %>%

  filter(RISK_LEVEL=='3 - Elevated') %>%

  filter([[j]]==1) %>%

  sample_n(high_count[[i]])

}
}

#turns list of dataframes into one dataframe
high_samp<-bind_rows(high_samp)

dplyr, похоже, не нравится приведенный ниже фрагмент, поскольку он не принимает нижний индекс в функции фильтра.

filter([[j]]==1)

1 Ответ

2 голосов
/ 17 июня 2020

Я создал фрейм данных спецификации spec, который объединяет groups и high_count. После этого я могу найти решение, используя lapply и оператор curly curly. Сначала я вычисляю sample_size и использую его для вызова функции sample_n.

library(dplyr)

###create sample data set
id <- c('l','m','n','o','p')
A <- c(0,1,1,1,1)
B <- c(1,1,1,0,1)
C <- c(1,1,1,0,1)
RISK_LEVEL <- c('3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated', '3 - Elevated')
data <- data.frame(id, A, B, C, RISK_LEVEL)

high_count<-c(1,3,2)
groups<-c('A','B','C')
spec <- data.frame(groups = groups, high_count = high_count, stringsAsFactors = FALSE)

result_list <- lapply(spec$groups, function(x) { 
  sample_size <- spec %>%
    filter(groups == {{x}}) %>%
    .$high_count
  result <- data %>% 
    filter(get(x) == 1) %>%
    sample_n(sample_size)
})

В результате получается:

> result_list
[[1]]
  id A B C   RISK_LEVEL
1  p 1 1 1 3 - Elevated

[[2]]
  id A B C   RISK_LEVEL
1  m 1 1 1 3 - Elevated
2  p 1 1 1 3 - Elevated
3  l 0 1 1 3 - Elevated

[[3]]
  id A B C   RISK_LEVEL
1  m 1 1 1 3 - Elevated
2  l 0 1 1 3 - Elevated

Что можно комбинировать с:

result <- bind_rows(result_list)
...