Точки дрожания на разные суммы в зависимости от состояния

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

Воспроизводимый пример:

#Create data frame with discrete X-axis values (a)
dat <- data.frame(a = c(rep(5, 5), rep(15,5), rep(25,5)), 
                  b = c(runif(5, 1, 2), runif(5, 2, 3), runif(5, 3, 4)))

#Plot raw, unjittered data
plot(dat$b ~ dat$a, data = dat, col = as.factor(dat$a), pch = 20, cex = 2)

введите описание изображения здесь

#vector of uncertainty estimates
wid_vec <- c(1,10,3)

#Ugly manual jittering, not feasible for large datasets but 
#produces the desired result
dat$a_jit <- c(jitter(rep(5, 5), amount = 1), 
                jitter(rep(15, 5), amount = 10), 
                jitter(rep(25, 5), amount = 3))

plot(dat$b ~ dat$a_jit, col = as.factor(dat$a), pch = 20, cex = 2)

введите описание изображения здесь

#Ugly loop solution, also works

newdat <- data.frame()
a_s <- unique(dat$a)

for (i in 1:length(a_s)){
  subdat       <- dat[dat$a == a_s[i],]
  subdat$a_jit <- jitter(subdat$a, amount = wid_vec[i])
  newdat <- rbind(newdat, subdat)
}

plot(newdat$b ~ newdat$a_jit, col = as.factor(newdat$a), pch = 20, cex = 2)

#Trying to make a vectorized solution, but this of course does not work.

jitter_custom <- function(x, wid){
  j <- x + runif(length(x), -wid, wid)
  j
}

#runif() does not work this way, this is shown to indicate the direction 
#I've been attempting

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

Ценю все предложения!

1 ответ

Решение

В качестве альтернативы

set.seed(1)
dat$a_jit <- c(jitter(rep(5, 5), amount = 1), 
                jitter(rep(15, 5), amount = 10), 
                jitter(rep(25, 5), amount = 3))

ты мог бы сделать

set.seed(1)
x <- with(dat, jitter(a, amount=setNames(c(1,10,3), unique(a))[as.character(a)]))

Результат тот же:

identical(x, dat$a_jit)
# [1] TRUE

Если вы хотите, чтобы предупреждение исчезло, вы можете обернуть suppressWarnings() вокруг jitter(...)или используйте что-то вроде with(dat, mapply(jitter, x=a, amount=setNames(c(1,10,3), unique(a))[as.character(a)])),

Другие вопросы по тегам