Написание функции для указания, какую комбинацию группы / переменной отправить в ggplot - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть фрейм данных, похожий на df:

ID = c(letters[1:10])
num = c(1000,1200,1234,980,1300,1400,1251,1111,1354,1256)
df <- data.frame(ID = rep(ID, num), num = sequence(num))
df[paste0('Var', seq_along(ID))] <- rnorm(length(ID) * sum(num))
df$Location = rep(c("alpha", "beta"), each = 6043)

Имеется 10 переменных, которые были измерены для нескольких лиц (каждая обозначена уникальным ID). Индивиды (ID с) вложены в Location, из которых 2 в этом примере. Так что ID sa: e принадлежит Location alpha, а ID sf: j принадлежит Location beta. Я создавал нужные мне графики, создавая новый объект, содержащий наблюдения для каждого уникального Location , Для каждой переменной (Var1:Var10) я строю все элементы этого Location на одном графике следующим образом:

#example plot for alpha
alpha <- df%>%
  filter(Location == "alpha")
ggplot(df, aes(x=num, y=Var1))+
  labs(x= "num(distance)",y="Variable")+
  geom_line(aes(color = ID))

В моем реальном наборе данных много комбинаций переменных / идентификаторов, поэтому я Пытаясь написать функцию, которую я могу просто предоставить Location и Var, которые я хочу использовать для создания одного и того же вида графика, я пробовал несколько вариантов этого, но у меня возникают проблемы с получением чего-либо для работы:

TSplot <- function(Location, Variable){
  ggplot(df, aes(x = num, y = Variable))+
      labs(x= "num(distance)", y=paste(Variable))+
  geom_line(aes(color = ID))
}

TSplot(alpha, Var1)

Ответы [ 3 ]

2 голосов
/ 16 апреля 2020

Есть несколько разных подходов к этому. Я попытался использовать то, что вы предоставили.

Один из способов - предоставить фрейм данных, а также расположение и переменную в виде строк для аргументов функции.

Если вы используете строки в Эстет c для ggplot, вы можете использовать aes_string.

library(tidyverse)

TSplot <- function(df_input, location, variable) {
  df_input %>%
    filter(Location == location) %>%
    ggplot(aes_string(x = "num", y = variable)) +
      labs(x = "num (distance)", y = variable) +
      geom_line(aes(color = ID))
}

TSplot(df_input = df, location = "alpha", variable = "Var1")
1 голос
/ 16 апреля 2020

Мне кажется, я понимаю ваш вопрос - спасибо за предоставленный полезный пример. Вы не опубликовали сообщение об ошибке, но я предполагаю, что если вы отправили TSplot(df, Location, Variable), вы получите сообщение об ошибке "Error in paste(Variable) : object 'variable' not found".

Это потому, что ggplot ожидает, что вы отправите "имя объект ", тогда как вы отправляете имя.

В качестве примера, скажем, вы позволили x быть этим вектором:

x <- c('red', 'blue')

Вы можете вспомнить этот вектор (" именованный объект " ") если вы просто введете имя, консоль вернет сам объект (вектор):

> x
[1] "red"  "blue"  # I asked for the object called "x", I got the object itself

Но если вы отправите на консоль "x" (только имя), вы вернетесь "x", а не объект.

> "x"
"x"    # thanks, console.  That's what I typed.  Note this is not the object called "x"

Можно ли отправить «имя», или в этом случае просто «х», и вернуть объект? Да! Для этого вы используете функцию get(), , которая возвращает значение именованного объекта :

> get("x")   # asking for the object named "x"
[1] "red"  "blue"   # I get the object, not the name

Так что теперь должно быть очевидно, как вы измените свою функцию на работу. Вы можете отправить в функцию имя объекта: function(df), например, будет отправлять «весь ваш объект данных» в функцию. Но это не работает для отправки имени компонента внутри этого именованного объекта. Вы можете отправить имя столбца как df$column.name, но оно не будет работать для отправки function(column.name), потому что если вы введете column.name в консоль, вы не получите df$column.name.

. Вы можете сделайте так, чтобы ваша функция работала, изменив ее так, чтобы вы включили get(), где вам нужно «получить» объект, используя только ссылочное имя, так что должно работать примерно так:

Tsplot <- function(df, Variable){
    ggplot(df, aes(x = num, y = get(Variable)))+
        labs(x= "num(distance)", y=paste(Variable))+
        geom_line(aes(color = ID))
}

Вы должны иметь возможность отправить Tsplot(df, 'Var1') и это будет работать. Если вы отправите Tsplot(df, Var1), он не будет работать.

В качестве альтернативы, если вы просто хотите отправить строку символов на aes(), вы можете просто использовать aes_string(). Если вы комбинируете вызовы с использованием символов и имен объектов, возможно, лучше использовать aes() вместе с get(). Другими словами, aes(x=name, y=get(character)) делает это за один aes() вызов, но с aes_string() вам придется использовать два: aes(x=name), aes_string(y=character).

О, и я угадайте, что это отрывок вашей полной функции , так как пример, который вы разместили там, не включал "Location". То же самое и там.

0 голосов
/ 16 апреля 2020

Я плохо понял структуру ваших данных, но вы пробовали:

TSplot <- function(df_input ,Location, Variable){
df=df_input  
ggplot(df, aes(x=num, y=Var1))+
  labs(x= "num(distance)",y="Variable")+
  geom_line(aes(color = ID))

}


newdata <- df[ which(df$Location=="alpha"), ]  # we select rows with criterion = "alpha"

TSplot(newdata,Location, Variable) # we plot the wanted data
...