Как перетасовать один столбец фрейма данных на основе значения строки в R?

#r

#r

Вопрос:

У меня есть спортивный набор данных, который выглядит следующим образом:

 season  team   tm  region 
2015    sharks shk  north
2015    dogs   dgs  south
2015    bears  brs  south
2015    cats   cts  north
2015    cows   cws  north
2014    sharks shk  north
2014    dogs   dgs  south
2014    bears  brs  south
2014    cats   cts  north
2014    cows   cws  north
 

Я хочу перетасовать столбец region, который я знаю, как это сделать. Однако для каждого года (2015 и 2014) должно быть 3 «север» и 2 «юг». Кроме того, я хочу, чтобы 2015 и 2014 годы имели одинаковую случайную область для определенной команды. Итак, 2015 sharks и 2014 sharks должны иметь один и тот же регион даже после рандомизации. Это пример того, как может выглядеть рандомизация:

 season  team   tm  region 
2015    sharks shk  south
2015    dogs   dgs  south
2015    bears  brs  north
2015    cats   cts  north
2015    cows   cws  north
2014    sharks shk  south
2014    dogs   dgs  south
2014    bears  brs  north
2014    cats   cts  north
2014    cows   cws  north
 

Спасибо за помощь!

Ответ №1:

Я бы поступил следующим образом

     data = data.frame(
  stringsAsFactors = FALSE,
            season = c(2015L,2015L,2015L,2015L,
                       2015L,2014L,2014L,2014L,2014L,2014L),
              team = c("sharks","dogs","bears",
                       "cats","cows","sharks","dogs","bears","cats","cows"),
                tm = c("shk","dgs","brs","cts",
                       "cws","shk","dgs","brs","cts","cws"),
            region = c("north","south","south",
                       "north","north","north","south","south","north","north")
)
head(data)

north_south = sample(c("north", "south"), 5, prob = c(0.6, 0.4), replace = T)

data2 = data.frame(data, Region2 = rep(north_south, 2))
 

Комментарии:

1. Большое вам спасибо!

Ответ №2:

Учитывая ограничение на то, что регион должен реплицироваться каждый год, эта проблема сводится к случайному присвоению каждой команде региона, а затем повторению этого присвоения во всей остальной части вашего фрейма данных.

Давайте начнем с игрушечного набора данных, в котором есть три команды (я опускаю здесь акул и медведей, чтобы сделать пример немного меньше).

 df1 <- data.frame(
  season = c(rep(2015, 3), rep(2014, 3)),
  team = c("dogs", "cats", "cows", "dogs", "cats", "cows"),
  tm = c("dgs", "cts", "cws", "dgs", "cts", "cows")
)
df1
#>   season team   tm
#> 1   2015 dogs  dgs
#> 2   2015 cats  cts
#> 3   2015 cows  cws
#> 4   2014 dogs  dgs
#> 5   2014 cats  cts
#> 6   2014 cows cows
 

Теперь мы можем создать фрейм данных, содержащий отдельные команды:

 df2 <- data.frame(
  team = c("dogs", "cats", "cows")
)
df2
#>   team
#> 1 dogs
#> 2 cats
#> 3 cows
 

Мы можем добавить переменную в df2 called region , которая должна иметь два случайно равных значения "north" и одно случайно равное значение "south" (в вашем примере требуется три и два соответственно). Мы делаем это с помощью $ присваивания (эквивалент tidyverse с использованием dplyr будет mutate() ):

 df2$region <- sample(c("north", "north", "south"))
df2
#>   team region
#> 1 dogs  north
#> 2 cats  south
#> 3 cows  north
 

Последний шаг — создать df2 резервную копию с df1 помощью using merge() (эквивалент tidyverse с использованием dplyr будет left_join() ):

 df <- merge(df1, df2)
df
#>   team season   tm region
#> 1 cats   2015  cts  south
#> 2 cats   2014  cts  south
#> 3 cows   2015  cws  north
#> 4 cows   2014 cows  north
#> 5 dogs   2015  dgs  north
#> 6 dogs   2014  dgs  north
 

Обратите внимание, что merge() здесь изменяется порядок строк и столбцов, в то dplyr::left_join() время как сохраняется порядок строк и столбцов первого аргумента:

 dplyr::left_join(df1, df2)
#> Joining, by = "team"
#>   season team   tm region
#> 1   2015 dogs  dgs  north
#> 2   2015 cats  cts  south
#> 3   2015 cows  cws  north
#> 4   2014 dogs  dgs  north
#> 5   2014 cats  cts  south
#> 6   2014 cows cows  north
 

Подробнее о соединениях с акцентом на подход tidyverse ( dplyr::left_join() и другие) смотрите По этой ссылке.

Комментарии:

1. Отлично, большое спасибо!

2. @yoyoman32, если вы считаете, что ответ был правильным, пожалуйста, отметьте его как правильный и / или поддержите его, чтобы другие с большей вероятностью прочитали его и нашли в нем помощь — спасибо!