dplyr sample_n одной переменной через другую - PullRequest
0 голосов
/ 27 мая 2019

У меня есть фрейм данных с «группирующей» переменной season и другой переменной year, которая повторяется для каждого месяца.

df <- data.frame(month = as.character(sapply(month.name,function(x)rep(x,4))),
                  season = c(rep("winter",8),rep("spring",12),rep("summer",12),rep("autumn",12),rep("winter",4)), 
                  year = rep(2021:2024,12))

Я хотел бы использовать dplyr::sample_n или что-то похожее, чтобы выбрать 2 месяца в кадре данных для каждого сезона и оставить одинаковые месяцы для всех лет, например:

     month        season     year
1     January     winter     2021
2     January     winter     2022
3     January     winter     2023
4     January     winter     2024
5     February    winter     2021
6     February    winter     2022
7     February    winter     2023
8     February    winter     2024
9     March       spring     2021
10    March       spring     2022
11    March       spring     2023
12    March       spring     2024
13    May         spring     2021
14    May         spring     2022
15    May         spring     2023
16    May         spring     2024
17    June        summer     2021
18    June        summer     2022
19    June        summer     2023
20    June        summer     2024
21    July        summer     2021
22    July        summer     2022
23    July        summer     2023
24    July        summer     2024
25    October     autumn     2021
26    October     autumn     2022
27    October     autumn     2023
28    October     autumn     2024
29    November    autumn     2021
30    November    autumn     2022
31    November    autumn     2023
32    November    autumn     2024

Я не могу набрать df %>% group_by(season,year) %>% sample_n(2), поскольку он выбирает разные месяцы для каждого года.

Спасибо!

Ответы [ 2 ]

3 голосов
/ 27 мая 2019

Мы можем случайным образом sample 2 значения из month и filter их по группам.

library(dplyr)

df %>%
  group_by(season) %>%
  filter(month %in% sample(unique(month),2))


#   month    season  year
#   <chr>    <chr>  <int>
# 1 January  winter  2021
# 2 January  winter  2022
# 3 January  winter  2023
# 4 January  winter  2024
# 5 February winter  2021
# 6 February winter  2022
# 7 February winter  2023
# 8 February winter  2024
# 9 March    spring  2021
#10 March    spring  2022
# … with 22 more rows

Если для определенных групп существует менее 2 unique значений, мы можем выбрать min Imum между 2 и уникальными значениями в группе до sample.

df %>%
  group_by(season) %>%
  filter(month %in% sample(unique(month),min(2, n_distinct(month))))

Используя ту же логику с базой R, мы можем использовать ave

df[as.logical(with(df, ave(month, season, 
             FUN = function(x) x %in% sample(unique(x),2)))), ]
0 голосов
/ 27 мая 2019

Опция с использованием slice

library(dplyr)
df %>% 
   group_by(season) %>% 
    slice(which(!is.na(match(month, sample(unique(month), 2)))))
# A tibble: 32 x 3
# Groups:   season [4]
#   month    season  year
#   <fct>    <fct>  <int>
# 1 October  autumn  2021
# 2 October  autumn  2022
# 3 October  autumn  2023
# 4 October  autumn  2024
# 5 November autumn  2021
# 6 November autumn  2022
# 7 November autumn  2023
# 8 November autumn  2024
# 9 April    spring  2021
#10 April    spring  2022
# … with 22 more rows

Или с использованием base R

by(df, df$season, FUN = function(x) subset(x, month %in% sample(unique(month), 2 )))
...