Saya memiliki vektor rata-rata dan deviasi standar, dan saya ingin memplot densitas yang sesuai dengan rata-rata dan deviasi standar ini dalam plot yang sama menggunakan ggplot2. Saya menggunakan mapply dan gather untuk menyelesaikan masalah ini, tetapi cukup banyak baris kode untuk sesuatu yang menurut saya sepele:

library(dplyr)
library(tidyr)
library(ggplot2)

# generate data
my_data <- data.frame(mean =  c(0.032, 0.04, 0.038, 0.113, 0.105, 0.111),
                      stdev = c(0.009, 0.01, 0.01, 0.005, 0.014, 0.006), 
                      test = factor(c("Case_01", "Case_02", "Case_03", "Case_04",
                                      "Case_05", "Case_06")))

# points at which to evaluate the Gaussian densities
x <- seq(-0.05, 0.2, by = 0.001)

# build list of Gaussian density vectors based on means and standard deviations
pdfs <- mapply(dnorm, mean = my_data$mean, sd = my_data$stdev, MoreArgs = list(x = x),
               SIMPLIFY = FALSE)

# add group names
names(pdfs) <- my_data$test

# convert list to dataframe
pdfs <- do.call(cbind.data.frame, pdfs)
pdfs$x <- x

# convert dataframe to tall format
tall_df <- gather(pdfs, test, density, -x)

# build plot
p <- ggplot(tall_df, aes(color = test, x = x, y = density)) +
  geom_line() +
  geom_segment(data = my_data, aes(color = test, x = mean, y = 0, 
                                   xend = mean, yend = 100), linetype = "dashed") +
  coord_cartesian(ylim = c(-1, 100))
print(p)

masukkan deskripsi gambar di sinijawaban yang diterima menggunakan mapply, sehingga mengonfirmasi bahwa saya aktif jalur yang benar. Namun, yang tidak saya sukai dari jawaban itu adalah bahwa itu berarti kode keras dan deviasi standar dalam panggilan mapply. Ini tidak akan berfungsi dalam kasus penggunaan saya, karena saya membaca data nyata dari disk (tentu saja, di MRE saya melewatkan bagian pembacaan data untuk kesederhanaan). Apakah mungkin untuk menyederhanakan kode saya, tanpa mengorbankan keterbacaan, dan tanpa hard-coding vektor rata-rata dan standar deviasi dalam panggilan mapply?

EDIT mungkin panggilan ke mapply dapat dihindari dengan menggunakan paket mvtnorm, tetapi saya rasa itu tidak memberikan penyederhanaan nyata di sini. Sebagian besar kode saya muncul setelah panggilan ke mapply.

1
DeltaIV 9 November 2017, 17:31

1 menjawab

Jawaban Terbaik

Anda dapat menyimpan beberapa pengkodean menggunakan purrr::pmap_df, yang melakukan pengikatan baris secara otomatis setelah membuat bingkai data untuk setiap pasangan mean-stdev:

Asumsikan my_data memiliki kolom input dalam urutan atau mean, stdev, test dan test adalah kelas karakter.

library(purrr)
tall_df2 <- pmap_df(my_data, ~ data_frame(x = x, test = ..3, density = dnorm(x, ..1, ..2)))

Dengan data:

my_data <- data.frame(mean =  c(0.032, 0.04, 0.038, 0.113, 0.105, 0.111),
                      stdev = c(0.009, 0.01, 0.01, 0.005, 0.014, 0.006), 
                      test = c("Case_01", "Case_02", "Case_03", "Case_04", "Case_05", "Case_06"), 
                      stringsAsFactors = F)

Merencanakan:

p <- ggplot(tall_df2, aes(color = factor(test), x = x, y = density)) + 
      geom_line() +
      geom_segment(data = my_data, aes(color = test, x = mean, y = 0, 
                                       xend = mean, yend = 100), linetype = "dashed") +
      coord_cartesian(ylim = c(-1, 100))

print(p)

Memberikan:

enter image description here

2
Psidom 9 November 2017, 14:58