3

Say I have a data frame coefs where each row contains model coefficients for a curve.

coefs <- structure(list(a1 = c(1.22228259789383, 1.2064168157394, 1.09555089661994, 0.943947433470916, 0.883490658557721, 0.46125552320107), d = c(0.385227755933488, 0.457271644919152, 0.340063262461958, 0.305629949064525, 0.42459163183877, 0.425710112988664), g = c(0, 0, 0, 0, 0, 0), u = c(1, 1, 1, 1, 1, 1)), .Names = c("a1", "d", "g", "u"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L))

I'd like to use each row of the data frame to add a new curve to the plot based a defined function: (you may recognize it as a 2PL item response model)

TWOPL <- function(x,a1,b) {
  1 / (1 + exp(-a1*(x-(b))))
}

Based on this and this question I tried the following ggplot command but get the error that computation failed:

library(ggplot2)
p <- ggplot(coefs, aes(x = 0))
p + stat_function(fun = TWOPL) + xlim(-5,5)

I know that I need a way to give the various coefficients to the function. As a test, I tried the function with a fixed parameters to create 1 curve and it works, for example:

#1 curve based on fixed parameters
TWOPL_copy <- function(x) {
  1 / (1 + exp(-1.22*(x-(.385))))
}

p <- ggplot(data.frame(x = 0), aes(x = 0))
p + stat_function(fun = TWOPL_copy) + xlim(-5,5)

I'm wondering how I might send each row of the data frame to ggplot. An ideal next step would be to differentiate the colors of each line somehow.

1
  • I just came across this question (stackoverflow.com/questions/21686638/…) and a possible approach is to make a temporary data frame that extrapolates the y values, then pass that to ggplot2. Commented Mar 31, 2017 at 4:53

1 Answer 1

9

While you could call stat_function for each set of parameters or with some pain call it programmatically, it's simpler to do the calculations yourself:

library(tidyverse)

coefs %>% 
    mutate(curve = letters[row_number()]) %>%    # add curve name
    crossing(x = seq(-5, 5, .1)) %>%    # repeat each row for every occurence of x
    mutate(y = TWOPL(x, a1, d)) %>%    # compute y values
    ggplot(aes(x, y, color = curve)) + 
    geom_line()

The simplest way to create the curves programmatically is to add a list of stat_function calls to the plot. All aesthetics have to be iterated across, including color. An x aesthetic must be supplied, but if you set xlim, it doesn't matter what it is.

curves <- coefs %>% 
    mutate(curve = letters[row_number()]) %>% 
    pmap(function(...){
             dots <- data_frame(...)
             stat_function(data = dots, aes(0, color = curve), 
                           fun = function(x) TWOPL(x, dots$a1, dots$d), 
                           xlim = c(-5, 5))
    })

ggplot() + curves

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.