Динамический индексный объект строки не найден в пользовательской функции R - PullRequest
0 голосов
/ 29 июня 2018

Я пытаюсь передать целое число ("i") функции, в которой "i" используется в качестве индекса строки для фрейма данных. Тем не менее, делая это ...

user_definedFUN <- function (i){
  ...
  result <- df[i, "col_name"]
  ...
}

x <- user_definedFUN(1)

... выдает следующую ошибку:

Error in `[.data.frame`(df, i, "col_name") : 
object 'i' not found

Я уверен, что это простая проблема того, как я ссылаюсь на «i» в скобках (даже если это не достаточно просто для меня, чтобы найти решение); однако я предоставил дополнительные подробности ниже, если это необходимо.

data.frame:

gen_name <- c("Boomers","Gen X","Millenials","Gen Z")
gen_years <- c("1946 to 1964","1965 to 1980","1981 to 1996", "1997 to 2011")
gen_xmin <- c(11, 9, 5, 2)
gen_xmax <- c(15, 11, 8, 5)
GEN_G.labels <- data.frame(gen_name, gen_years, gen_xmin, gen_xmax)

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

Прямоугольники будут созданы с помощью следующей функции, которая будет вызываться из цикла и которой предоставляется индекс строки для определенного поколения (1 = "Boomers", 2 = "Gen X" и т. Д.)

genlabelsFUN <- function(i){
  # return a geom_rect()
  rv <- geom_rect(aes(
       xmin = GEN_G.labels[i, "gen_xmin"],
       xmax = GEN_G.labels[i, "gen_xmax"],
       ymin = 1000, 
       ymax = 1100)
     , fill = "red")
  return(rv)
}

ggplot(...snip...) +
   ...snip... +
   genlabelsFUN(1)

Функция работает, если используется значение статического индекса. Например, «GEN_G.labels [ 1 ,« gen_xmin »]» вместо «GEN_G.labels [ i ,« gen_xmin »]» помещает красный прямоугольник между 11 и 15 на ось х на 1000 по оси у с высотой 100. Хотя функция не имеет смысла без динамического аспекта «i».

На следующем изображении показан результат при использовании значения статического индекса (Примечание: я использую другой масштаб по оси Y в моем примере выше для простоты). Окончательный код будет проходить по каждой строке GEN_G.labels и запускать genlabelsFUN (), чтобы создать аналогичный прямоугольник для каждого поколения.

population age chart with red box indicating boomer generation

Спасибо

EDIT:

Полный ggplot

scaleFUN <- function(x) formatC( x / 1000, format = "f", big.mark = ",", digits = 0) #format as thousands with comma

ggplot(data = GEN_G.data_frame, aes(x = range, y = persons)) +
  geom_bar(stat = "identity") +
  theme_classic() +
  theme(
    axis.text.x = element_text(angle = 90, hjust = 1)) +
  scale_y_continuous(
    name = "Persons (thousands)",
    labels = scaleFUN) +
  genlabelsFUN(1)

РЕДАКТИРОВАТЬ 2:

Воспроизводимый пример (работает на основе комментария MrFlick ниже)

GEN_G.dataframe <- data.frame(
  range = c(1:21), 
  persons = abs(rnorm(21))*50)

GEN_G.labelsx <- data.frame(
  gen_name = c("Group A","Group B","Group C","Group D"), 
  gen_xmin = c(11, 9, 5, 2), 
  gen_xmax = c(15, 11, 9, 5))
GEN_G.labelsx$gen_name <- factor(
  GEN_G.labelsx$gen_name, 
  levels = GEN_G.labelsx$gen_name)


ggplot() +
  geom_bar(data=GEN_G.dataframe,aes(x=range, y=persons),stat="identity") +
  theme_classic() +
  theme(
    axis.text.x = element_text(angle = 90, hjust = 1)) +
  geom_rect(aes(
    xmin = gen_xmin,
    xmax = gen_xmax,
    ymin = 175, 
    ymax = 180,
    fill = gen_name),
    data = GEN_G.labelsx)

Выход из примера редактирования 2.

enter image description here

1 Ответ

0 голосов
/ 03 июля 2018

Вы не можете использовать переменные типа i внутри aes(). Символы внутри aes() не оцениваются, пока график не будет нарисован. R не может правильно захватить среду, если i определено таким образом, поэтому значение изменилось бы к моменту построения графика.

Однако я не думаю, что цикл / функция даже необходимы. Вы должны просто быть в состоянии сделать

geom_rect(aes(xmin=gen_xmin, xmax=gen_xmax), ymin=1000, ymax=1000, data=GEN_G.labels)

для использования другого data.frame для этого слоя. Тогда все коробки нарисованы одновременно без петли.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...