Как написать функцию для медианы, чтобы использовать ее для графика Ggplot, адаптируемого к различным элементам из набора данных в R

#r #function #ggplot2 #median

Вопрос:

Мне нужно создать один и тот же график для разных переменных моего набора данных. Мой набор данных выглядит так:

     df5 <-  structure(list(P54a = c(20, 4, 3, 5, NA, 9, 18, 18, NA, 4, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 17, 13, NA, NA, NA, NA), P79 = c(25, 
20, 12, NA, NA, 13, NA, NA, NA, 25, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 15, NA, 1, NA, NA), center = c(203, 203, 203, 203, 108, 
108, 206, 206, 206, 206, 116, 116, 116, 116, 116, 116, 116, 116, 
116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 
116, 116, 713, 713, 713, 718, 718, 718, 718)), row.names = c(NA, 
40L), class = "data.frame")
 

Я написал код для одной переменной, и, похоже, он работает нормально. Чтобы избежать копирования одного и того же кода несколько раз, я хотел создать функцию, которая позволила бы мне использовать эту функцию, просто определив интересующую переменную и центр.
Код для «отдельного элемента» P54a и для центра 206 выглядит следующим образом:
(центр 713 будет центром, который я сравниваю с центром 206, «эталонным центром»)

 a<-df5 %>% 
    group_by(center) %>%
    summarise(P54a = median(P54a, na.rm=T)) 
  a$center=factor(a$center, levels = a$center)
  a %>%
    mutate(center = fct_reorder(center,P54a)) ->a
  
  b<-a$P54a[which(a$center==713)] #pick the value of the reference center
  a1 <- a %>% 
    group_by(center) %>% 
    mutate(my_label = ifelse(center %in% c("206","713"),
                             paste(center,P54a, sep = ":"), NA)) %>% 
    ungroup()
  
  d <- ggplot(data=a1,aes(x=center,label=center,y=P54a,
                          fill=factor(ifelse(center=="206","target",ifelse(center== "713","Reference","all")))))  
    geom_bar(stat= "identity")  
    scale_fill_manual(name = "center", values=c("cadetblue","gold", "orange"))  
    xlab("TitelX")  
    ylab("Median")  
    ggtitle("Titelgraph")  
    #d<- d  theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),legend.position = "none") 
    geom_hline(aes(yintercept= b), data= filter(a1, center== 713), color="black", linetype="dashed")   ylim(0, 20) 
    #geom_text_repel(aes(label = my_label),size= 3, box.padding = 0.5 , max.overlaps = Inf)
    theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),legend.position = "none")   
    geom_label(label=a1$my_label, vjust = -0.1)
   d
 

Попытка, которая не сработала:

  bar_plot <- function(itemNo, # would be the defined item
                         df = df5, # the full dataset 
                         target= target_center (in my example the 206)
    ){
    
      df1 <- subset(df5, select= itemNo)
      df2 <- subset(df5, select= center)# the original dataset has other variables that's why I would here select the center item.
      df6 <- cbind(df1, df2)
    
    
    a<-df6 %>% group_by(center) %>% summarise(med_x = median(itemNo, na.rm=T)) a$center=factor(a$center, levels = a$center) a %>% mutate(center = fct_reorder(center,med_x)) ->a
    
    b<-a$itemNo[which(a$center==713)] #pick the value of the reference center 
    a1 <- a %>% group_by(center) %>% mutate(my_label = ifelse(center %in% c("target","713"), paste(center,itemNo, sep = ":"), NA)) %>% ungroup()
    
    d <- ggplot(data=a1,aes(x=center,label=center,y=itemNo, fill=factor(ifelse(center=="target","target",ifelse(center== "713","Reference","all")))))  
 geom_bar(stat= "identity")   scale_fill_manual(name = "center", values=c("cadetblue","gold", "orange"))   xlab("TitelX")   
ylab("Median")   ggtitle("Titelgraph")    geom_hline(aes(yintercept= b), data= filter(a1, X0== 713), color="black", linetype="dashed")   ylim(0, 20)  
theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),legend.position = "none")   geom_label(label=a1$my_label, vjust = -0.1) 
    return(d)
 

Первая проблема начинается с медианы, она принимает не значения определенной переменной/элемента, а имя элемента и вставляет в качестве медианы имя переменной.
Это первый раз, когда я пишу функции.., Я пытался найти решение в предыдущих вопросах/ответах, но это не сработало.. например, используя для медианы :

 median = numeric(0)
  for( i in 1:ncol(df5)){
    median[i] = median(df5[,i], na.rm=TRUE)
  }
 

Любая помощь очень приветствуется. Большое спасибо

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

1. Возможно, вам будет намного проще помочь, если вы предоставите образец своих данных вместе с кодом thte

2. @GuedesBF Спасибо вам и извините за это. Надеюсь, теперь тебе лучше.

3. @Sunshine_student решает ли мой ответ вашу проблему? Взгляните на это.

Ответ №1:

Ошибка, которую вы получаете, понятна, потому что вы вызываете имя столбца внутри функции. Но есть еще две вещи, которые вы должны иметь в виду, ИМО:

  1. Когда вы завершаете свой код функцией, всегда старайтесь запускать его построчно внутри функции со значениями параметров функции, уже определенными в глобальной среде. Это позволит вам легко обнаружить ошибку. Как я сделал это здесь. Я взял ваш код, который работал, а затем завернул его с необходимыми изменениями.
  2. То, как вы определили функциональные входные параметры, а затем продолжили использовать их внутри функции, неверно. Взгляните на мой код, вы поймете разницу.

Функция:

 bar_plot <- function(itemNo, df5, center){
  
  df1 <- subset(df5, select= itemNo)
  df2 <- subset(df5, select= center)
  df6 <- cbind(df1, df2)
  
  a<-df6 %>% 
    group_by(center) %>%
    summarise(itemNo = median(!! sym(itemNo), na.rm=T)) 
  a$center=factor(a$center, levels = a$center)
  a %>%
    mutate(center = fct_reorder(center,itemNo)) ->a
  
  b<-a$itemNo[which(a$center==713)] #pick the value of the reference center
  a1 <- a %>% 
    group_by(center) %>% 
    mutate(my_label = ifelse(center %in% c("206","713"),
                             paste(center,itemNo, sep = ":"), NA)) %>% 
    ungroup()
  
  d <- ggplot(data=a1,aes(x=center,label=center,y=itemNo,
                          fill=factor(ifelse(center=="206","target",ifelse(center== "713","Reference","all")))))  
    geom_bar(stat= "identity")  
    scale_fill_manual(name = "center", values=c("cadetblue","gold", "orange"))  
    xlab("TitelX")  
    ylab("Median")  
    ggtitle("Titelgraph")  
    #d<- d  theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),legend.position = "none") 
    geom_hline(aes(yintercept= b), data= filter(a1, center== 713), color="black", linetype="dashed")   ylim(0, 20) 
    #geom_text_repel(aes(label = my_label),size= 3, box.padding = 0.5 , max.overlaps = Inf)
    theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(),legend.position = "none")   
    geom_label(label=a1$my_label, vjust = -0.1)
  d
  
}
 

Теперь вызовите его и посмотрите результат:

 bar_plot('P54a', df5, 206)

 

1-й выход

Другой:

 bar_plot('P79', df5, 206)
 

2-й Выход

Дайте мне знать, если у вас возникнут какие-либо вопросы.

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

1. большое спасибо! Это работает для разных переменных да , большое вам спасибо. Для центра еще нет, но, может быть, я смогу разобраться в этом сейчас;)