Как использовать sec_axis () для дискретных данных в ggplot2 R?

У меня есть скрытые данные, которые выглядят так:

height <- c(1,2,3,4,5,6,7,8)
weight <- c(100,200,300,400,500,600,700,800)
person <- c("Jack","Jim","Jill","Tess","Jack","Jim","Jill","Tess")
set <- c(1,1,1,1,2,2,2,2)
dat <- data.frame(set,person,height,weight)

Я пытаюсь построить график с той же осью x (человек) и двумя разными осями y (вес и рост). Во всех примерах, которые я нахожу, я пытаюсь построить вторичную ось (sec_axis) или дискретные данные с использованием базовых графиков. Есть ли простой способ использовать sec_axis для скрытых данных на ggplot2? Изменить: кто-то в комментариях предложил мне попробовать предложенный ответ. Однако сейчас я столкнулся с этой ошибкой

Вот мой текущий код:

p1 <- ggplot(data = dat, aes(x = person, y = weight)) + 
  geom_point(color = "red") + facet_wrap(~set, scales="free") 
p2 <- p1 + scale_y_continuous("height",sec_axis(~.*1.2, name="height"))
p2

I get the error: Error in x < range[1] : 
  comparison (3) is possible only for atomic and list types

В качестве альтернативы, теперь я изменил пример, чтобы он соответствовал этому опубликованному примеру.

p <- ggplot(dat, aes(x = person))
p <- p + geom_line(aes(y = height, colour = "Height"))

# adding the relative weight data, transformed to match roughly the range of the height
p <- p + geom_line(aes(y = weight/100, colour = "Weight"))

# now adding the secondary axis, following the example in the help file ?scale_y_continuous
# and, very important, reverting the above transformation
p <- p + scale_y_continuous(sec.axis = sec_axis(~.*100, name = "Relative weight [%]"))

# modifying colours and theme options
p <- p + scale_colour_manual(values = c("blue", "red"))
p <- p + labs(y = "Height [inches]",
              x = "Person",
              colour = "Parameter")
p <- p + theme(legend.position = c(0.8, 0.9))+ facet_wrap(~set, scales="free") 
p

Я получаю сообщение об ошибке

"geom_path: Each group consists of only one observation. Do you need to 
 adjust the group aesthetic?"

Я получаю шаблон, но точки не отображаются


person Ash    schedule 04.09.2017    source источник
comment
Это непрерывные данные (числа), а не дискретные (категории).   -  person Brian    schedule 05.09.2017
comment
Я понял, что связал неправильный источник. Я связал правильный и обновил свой ответ с ошибкой, если я его использую   -  person Ash    schedule 05.09.2017
comment
Добавьте sec.axis = перед своим sec_axis(...). Без явного наименования аргумента по умолчанию используется 2-й аргумент в scale_y_continuous(), & breaks = sec_axis(~.*1.2, name="height") вызывает эту ошибку, потому что она не имеет смысла в контексте.   -  person Z.Lin    schedule 05.09.2017
comment
Как это p1 + scale_y_continuous("height", sec_axis(sec.axis= ~.*1.2, name="height"))? Это вызывает у меня ошибку   -  person Ash    schedule 05.09.2017
comment
Насколько я знаю, ggplot2 не поддерживает независимую вторичную ось. Все вторичные оси должны быть основаны на однозначном преобразовании первичных осей.   -  person LVG77    schedule 05.09.2017
comment
Я думаю, что так было несколько лет назад, но теперь у них, кажется, есть sec_axis, который, кажется, выполняет работу за других. Не могу заставить это работать для меня.   -  person Ash    schedule 05.09.2017


Ответы (1)


Аргументы функции R вводятся по позиции, если имена аргументов не указаны явно. Как упомянул @ Z.Lin в комментариях, вам нужно sec.axis= перед вашей sec_axis функцией, чтобы указать, что вы вводите эту функцию в sec.axis аргумент scale_y_continuous. Если вы этого не сделаете, он будет передан во второй аргумент scale_y_continuous, который по умолчанию равен breaks=. Таким образом, сообщение об ошибке связано с тем, что вы не вводите допустимый тип данных для аргумента breaks:

p1 <- ggplot(data = dat, aes(x = person, y = weight)) + 
  geom_point(color = "red") + facet_wrap(~set, scales="free") 
p2 <- p1 + scale_y_continuous("weight", sec.axis = sec_axis(~.*1.2, name="height"))
p2

! [введите здесь описание изображения

Первый аргумент (name=) scale_y_continuous предназначен для первой шкалы y, тогда как аргумент sec.axis= - для второй шкалы y. Я изменил ваше первое название шкалы Y, чтобы исправить это.

person acylam    schedule 05.09.2017
comment
Но это не похоже на график веса и роста. Мне нужно, чтобы вес и рост были нанесены на одну и ту же ось абсцисс. - person Ash; 05.09.2017
comment
@Ash Просто неправильно указан ярлык. См. Мой отредактированный ответ. - person acylam; 05.09.2017
comment
Нет. Я не думаю, что вы понимаете мою точку зрения. Для каждого человека, например. В Наборе 1 для Джека я должен видеть две точки: одна соответствует его росту (например, отмечена красным), а другая - его весу (например, отмечена черным). Вместо этого сюжет здесь дает единичные баллы, возможно, взаимосвязь между весом и ростом? Я не этого хочу. - person Ash; 05.09.2017
comment
@ Аш, я вижу, вам действительно нужны две разные оси Y на одном и том же графике. В этом случае sec.axis не является правильным решением, поскольку он допускает только вторую ось, которая является линейным преобразованием первой оси. Я думаю, что с ggplot2 нет хороших решений, потому что это сделано для предотвращения искажения данных. См. Это обсуждение: stackoverflow.com/questions/3099219/ - person acylam; 05.09.2017