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

#r #dataframe #random #replace #na

#r #dataframe #Случайный #заменить #na

Вопрос:

У меня есть dataframe с разными группами (идентификаторами) разного размера. Внутри каждой группы я хотел бы случайным образом заменить определенный процент значений в столбце «значение» (скажем, 30%) на NA. Вот упрощенная версия моих данных:

 ID<-rep(c("X1","X2"),times=c(3,6))
value<-c(1,2,3,1,2,3,4,5,6)
df1 <- data.frame(ID,value)
df1
ID value
X1     1
X1     2
X1     3
X2     1
X2     2
X2     3
X2     4
X2     5
X2     6
  

Вот что я хотел бы иметь:

 ID value
X1     1
X1     NA
X1     3
X2     1
X2     2
X2     NA
X2     4
X2     5
X2     NA
  

Есть идеи, как я мог бы это сделать? Я предпочитаю использовать tidyverse, но если у вас есть другие варианты, это также будет оценено!

Ответ №1:

Мы можем использовать dplyr . Сгруппированный по «ID», получите индекс или 30% строк с sample помощью и используйте его replace для замены «значения» на NA

 library(dplyr)
df1 %>%
    group_by(ID) %>%
    mutate(value =  replace(value, sample(row_number(),  
           size = ceiling(0.3 * n()), replace = FALSE), NA) )
# A tibble: 9 x 2
# Groups:   ID [2]
#  ID    value
#  <chr> <dbl>
#1 X1       NA
#2 X1        2
#3 X1        3
#4 X2       NA
#5 X2        2
#6 X2       NA
#7 X2        4
#8 X2        5
#9 X2        6
  

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

1. Привет, у меня возникли проблемы с использованием вашего ответа. когда я запускаю этот код, я получаю следующую ошибку: «n()` должен использоваться только внутри глаголов dplyr.». Есть идеи, откуда это взялось?

2. @Cam здесь n() используется в dplyr синтаксисе ie. in mutate . Не уверен, как появляется эта ошибка? Можете ли вы показать packageVersion('dplyr')

3. @Cam В вашем вводимом коде были некоторые опечатки. Я только что отредактировал их в вашем сообщении. Можете ли вы протестировать сейчас

4. это версия 1.0.1! И я попробую протестировать это сейчас.

5. да, это было так! Запуск нового сеанса сделал свое дело. Большое спасибо!!

Ответ №2:

Предполагая, что данные находятся в df

 df[sample(seq(nrow(df)), nrow(df) *0.3), "value"] <- NA
  

Ответ №3:

Вы можете использовать sample() для получения случайных индексов ваших данных.

Вы могли бы попробовать это

 df <- data.frame(ID = paste("X", 1:10),
                 value = rnorm(10))

fraction <- 0.30

df$value[sample(1:length(df$value), size = round(length(df$value) * fraction))] <- NA

#30% of the values in df$value will then be NA