0

I am creating a function that automatically plots curves based on user input. Using the curve() function in base R I managed to plot it like this: enter image description here

I would prefer, however, to use ggplot2 instead of base R, but it seems that I need to create a geom_function() line for every curve instead of it being determined automatially based on user input. Is there a solution using loops or maybe lapply? Here is a recreation of my data and the part of the script for plotting that I used with base R:

df<-data.frame(
  PseudoA=c(0.3287622, 0.8539452, 0.3293448, 0.1859212, 0.7030731, 0.1382480, 0.4184386, 1.0786543, 1.3189188, 0.9217081, 2.6668777),
  PseudoB=c(1.0387213, -0.4028699,  0.3206788,  0.8403824, -0.3619186, 0.22062480, -2.95486273, -1.73832891, -1.54281422, -0.44192827, -0.78999262),
  items<-c('i1','i2','i3','i4','i5','i6','i7','i8','i9','i10','i11')
)

rownames(df)<-df$items  

p<-list()
eq<- function(x){(1/(1+2.71828^(-1.7*(df$PseudoA[1]*(x-df$PseudoB[1])))))}
p<-curve(eq, col="white", xlim=c(-4,4),ylim=c(0,1), xlab="Level of Trait", ylab="p(1.0)")# setting up an empty plot to add the curves
colors<-rainbow(n = nrow(df))

for(i in 1:11){
  eq<-function(x){(1/(1+2.71828^(-1.7*(df$PseudoA[i]*(x-df$PseudoB[i])))))}
  p[i]<-curve(eq, col=colors[i], xlim=c(-4,4), ylim=c(0,1), main="Item Characteristic Curve", lwd=3,add=TRUE)
  legend(x=-4, y=1, legend=rownames(df), fill=colors, pt.cex=3)
  p
}

Keep in mind that the user would specify the range in the loop (instead of being 1:11 it could be any other range, like 5:9). Any tips would be appreciated!

Diego
  • 31
  • 2
  • With the solution from the existing question, you could do something like `df %>% crossing(x = seq(-4,4,.1)) %>% mutate(y=1/(1+2.71828^(-1.7*(PseudoA*(x-PseudoB))))) %>% ggplot() + aes(x, y, color=items) + geom_line()` after running `library(tidyverse)`. If you want to only do a subset of the lines, just filter the values before the `crossing()` step. – MrFlick Jun 02 '23 at 19:04

0 Answers0