У меня есть такие данные:

student.id <- c("142", "142", "567", "567", "347", "347", "567", "945")
flag.double <- c("1", "1", "1", "1", "1", "1", "0", "0")
data <- data.frame(student.id, flag.double)

Я хочу сгруппировать по student.id, отфильтровать до студентов, у которых есть flag.double==1, и случайным образом выбрать одно наблюдение студента (из двух доступных экземпляров студентов). Затем я хочу снова объединить это с данными.

Это дает мне случайные наблюдения, которые я хочу:

flag <- data %>% 
  group_by(student.id) %>% 
  filter(flag.double==1) %>% 
  sample_n(flag.double, replace = T)

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

Затем я только что присоединил это обратно к набору данных.

data <- left_join(data, flag)

Все РАБОТАЕТ хорошо, но мне не нравится, насколько все это выглядит неэффективным. Мне также не нравится создавать новый фрейм данных только для того, чтобы присоединить его обратно к исходному. Есть ли более элегантный способ сделать это с помощью dplyr, tidyr, plyr, pipe?

-1
NewBee 21 Ноя 2019 в 04:29

2 ответа

Если я правильно понимаю, что вы хотите выбрать одно наблюдение из дублированных student.id s, вы можете создать дополнительный столбец, указывающий эту процедуру выборки:

set.seed(123)
library(dplyr)
data.frame(
    student.id = c("142", "142", "567","567","347","347", "567", "945"),
    flag.double = c("1","1","1", "1","1", "1","0", "0"),
    x = rnorm(8) # other data for expository purposes
  ) %>%
  group_by(student.id) %>%
  mutate(in_sample = ifelse(flag.double == 1, sample(0:1), NA))
#> # A tibble: 8 x 4
#> # Groups:   student.id [4]
#>   student.id flag.double       x in_sample
#>   <fct>      <fct>         <dbl>     <int>
#> 1 142        1           -0.560          1
#> 2 142        1           -0.230          0
#> 3 567        1            1.56           0
#> 4 567        1            0.0705         1
#> 5 347        1            0.129          0
#> 6 347        1            1.72           1
#> 7 567        0            0.461         NA
#> 8 945        0           -1.27          NA

Создано в 2019–20–20 годах с помощью представительного пакета (v0.3.0)

1
sboysel 21 Ноя 2019 в 05:13
Это именно то, что я хотел, спасибо!
 – 
NewBee
21 Ноя 2019 в 19:15

Если вам просто нужно взять один, а столбцов всего два, то сработает следующее:

data %>% distinct(student.id,flag.double)

Если у вас есть другой столбец значений, и можно выбрать первый:

data$row <- 1:nrow(data)
data[!duplicated(data[,c("student.id","flag.double")]),]

Если у вас есть другой столбец значений, и вам действительно нужно выполнить выборку:

data %>% group_by(student.id,flag.double) %>% sample_n(1)

Предполагая, что ваш flag.double правильный, это работает, потому что те, у которых 0 как flag.double, должны быть уникальными для id. Следовательно, вы можете просто сгруппировать по обеим переменным, а затем выбрать

0
StupidWolf 21 Ноя 2019 в 13:32