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

#r #dplyr #tidyverse #slice

Вопрос:

У меня есть фрейм данных

 ID1 ID2 ID3 feat1 feat2
1 a x class1 class2
1 a y class1 class2
1 b x class2 class1
1 b y class2 class1
1 b z class2 class1
1 c x class1 class1
2 a x class1 class2
2 a y class1 class2
2 b x class2 class1
2 b y class2 class1
2 b z class2 class1
2 c x class1 class1
 

сгруппированы по ID1, ID2 и ID3

Я хочу случайным образом перетасовать значения feat1 и feat2 (класс 1 или класс 2) между уровнями групп (то есть между a, b и c) без замены. Так что случайный вывод может быть:

 ID1 ID2 ID3 feat1 feat2
1 a x class2 class1
1 a y class2 class1
1 b x class1 class1
1 b y class1 class1
1 b z class1 class1
1 c x class1 class2
2 a x class2 class1
2 a y class2 class1
2 b x class1 class1
2 b y class1 class1
2 b z class1 class1
2 c x class1 class2
 

В этом случайном перемешивании » a » берет значения функций из «b» ; «b» берет их из «c»; и «c» из «a»

Мой код таков

 my_df_reshuffled = my_df %>%
  group_by(ID1, ID2, ID3) %>%
  slice(sample(1:n()))
 

Но он не перемешивает значения между группами, просто изменяет порядок групповых уровней, сохраняя значения feat1 и feat2 для каждой группы равными.

Чего мне не хватает?

Спасибо

Ответ №1:

Если я правильно понял, я думаю, что это может вам помочь

Данные

 df <- structure(list(ID1 = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L), ID2 = c("a", "a", "b", "b", "b", "c", "a", "a", "b", 
"b", "b", "c"), ID3 = c("x", "y", "x", "y", "z", "x", "x", "y", 
"x", "y", "z", "x"), feat1 = c("class1", "class1", "class2", 
"class2", "class2", "class1", "class1", "class1", "class2", "class2", 
"class2", "class1"), feat2 = c("class2", "class2", "class1", 
"class1", "class1", "class1", "class2", "class2", "class1", "class1", 
"class1", "class1")), class = "data.frame", row.names = c(NA, 
-12L))
 

Код

 df %>% 
  group_by(ID1) %>% 
  mutate(across(.cols = starts_with("feat"),
                .fns = function(x)sample(x,length(x))))
 

Выход

 # A tibble: 12 x 5
# Groups:   ID1 [2]
     ID1 ID2   ID3   feat1  feat2 
   <int> <chr> <chr> <chr>  <chr> 
 1     1 a     x     class2 class1
 2     1 a     y     class2 class1
 3     1 b     x     class2 class2
 4     1 b     y     class1 class1
 5     1 b     z     class1 class1
 6     1 c     x     class1 class2
 7     2 a     x     class1 class1
 8     2 a     y     class1 class2
 9     2 b     x     class2 class1
10     2 b     y     class1 class2
11     2 b     z     class2 class1
12     2 c     x     class2 class1