готовая версия применения функции к случайным строкам

#r #dplyr

#r #dplyr

Вопрос:

Предыстория

Я генерирую некоторые образцы данных, которые я хочу использовать, чтобы показать некоторые простые аналитические операции в Spark. Контекст Spark здесь не имеет значения.

Пример данных

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

 library("tidy verse")
set.seed(123)
dta_ts <-
  tibble(category = sample(LETTERS[1:4], replace = TRUE, size = 1e5)) %>% 
  group_by(category) %>%
  mutate(ref_dte = sample(
    x = seq(as.Date('2010-01-01'), as.Date('2016-12-30'), by = "1 day"),
    size = n(),
    replace = TRUE
  )) %>%
  ungroup() %>% 
  distinct() %>% 
  mutate(rand_val = rpois(n(), lambda = 10))
  

Вопрос

Я хотел бы вставить некоторые выбросы в данные. В базе R этого легко достичь с помощью:

 # Add outliers
for (i in sample(1:nrow(dta_ts), 50)) {
  dta_ts[i,3] <- sample(1e4:1e6, 1)
}
  

Проблема

Предоставленное решение, возможно, неэффективно и неэлегантно. Я хотел бы найти dplyr-иш способ достижения того же результата.. Я знаю о sample_n и sample_frac , но меня не интересует выборка данных, только доступ к строке случайного выбора. Идеальным решением было бы функционировать как последующее дополнение к конвейеру, приведенному ниже:

 ... %>%
mutate(rand_val = rpois(n(), lambda = 10)) %>%
# On random outliers are created
  

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

1. Цикл for не нужен: dta_ts[sample.int(nrow(dta_ts), size = 50), 3] <- sample(1e4:1e6, size = 50) был бы эффективным и элегантным

Ответ №1:

Вы можете генерировать случайные n значения от 1 до количества строк в данных и replace их с n высокими значениями из 1e4:1e6 .

 library(dplyr)
n <- 50

dta_ts %>%
    mutate(rand_val = replace(rand_val, sample(n(), n), sample(1e4:1e6, n)))
  

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

Вы также можете использовать ту же логику в базе R.

 transform(dta_ts, 
    rand_val = replace(rand_val, sample(nrow(dta_ts), n), sample(1e4:1e6, n)))
  

Ответ №2:

Мы также можем использовать case_when

 library(dplyr)
n <- 50
dta_ts %>%
     mutate(rand_val = case_when(row_number() %in% sample(n(), n) ~ sample(1e4:1e6),  TRUE ~ rand_val))
  

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

 i1 <- sample(nrow(dta_ts), n)
dta_ts$rand_ts[i,1] <- sample(1e4:1e6, n)