Как добавить несколько вертикальных линий в ggplot через итерацию? [Дубликат]

В C # конструктор вызывается при создании экземпляра класса. Он не имеет типа возврата, поскольку он ничего не возвращает. Я обычно использую его для создания свойств класса, для которых требуется ссылка на объект, например объекты коллекции, пользовательские объекты (классы), другие объекты, требующие создания экземпляра. Разработчик C # не должен быть написан программистом. Если вы его не пишете, компилятор автоматически сгенерирует его, а затем вызовет его.

Конструкторы также могут быть перегружены. Таким образом, вы можете иметь несколько конструкторов с разными типами параметров. Если вы действительно перегрузите конструктор, обязательно включите пустой конструктор без параметров в случае, если есть какие-либо вызовы класса, которые не передаются ни в какие параметры.

  public class MyClass {  public List & lt; int & gt;  MyIntList {get;  задавать;  } MyClass () {} MyClass (int i) {MyIntList = new List & lt; int & gt; ();  MyIntList.Add (int i);  }}  
9
задан user3799203 7 October 2014 в 13:18
поделиться

3 ответа

Причина, по которой это происходит, связана с «ленивой оценкой» ggplot. Это обычная проблема, когда ggplot используется таким образом (делая слои отдельно в цикле, вместо того, чтобы иметь для него ggplot, как в решении @ hrbrmstr).

ggplot сохраняет аргументы aes(...) как выражения и оценивает их только при отображении графика. Таким образом, в ваших циклах, что-то вроде

aes(y = df[,p], colour = place[p-1])

сохраняется, как есть, и оценивается при визуализации графика после завершения цикла. На этом этапе p = 3, поэтому все графики отображаются с p = 3.

Таким образом, «правильный» способ сделать это - использовать melt(...) в пакете reshape2, чтобы конвертировать ваши данные от широкого до длинного формата, и пусть ggplot управляет слоями для вас. Я ставлю «правильно» в кавычки, потому что в этом конкретном случае есть тонкость. При расчете распределений для скрипки с использованием кадра расплавленных данных ggplot использует общую сумму (как для Чикаго, так и для Майами) в качестве шкалы. Если вы хотите, чтобы скрипки были основаны на частоте, масштабируемой по отдельности, вам нужно использовать петли (к сожалению).

Путь вокруг ленивой проблемы оценки заключается в том, чтобы ссылаться на индекс цикла в определении data=.... Это not сохраняется как выражение, фактические данные хранятся в определении графика. Поэтому вы можете сделать это:

g <- ggplot(df,aes(x=topic))
for (p in 2:length(df)) {
  gg.data <- data.frame(topic=df$topic,value=df[,p],city=names(df)[p])
  g <- g + geom_violin(data=gg.data,aes(y=value, color=city))
}
g

[/g2]

, который дает тот же результат, что и ваш. Обратите внимание, что индекс p не отображается в aes(...).


Обновление: примечание о scale="width" (упомянутое в комментарии). Это приводит к тому, что все скрипки имеют одинаковую ширину (см. Ниже), что не такое же масштабирование, как в исходном коде OP. IMO - это отличный способ визуализировать данные, так как предполагает, что в группе Чикаго имеется гораздо больше данных.

ggplot(gg) +geom_violin(aes(x=topic,y=value,color=variable),
                        alpha=0.3,position="identity",scale="width")

[/g3]

9
ответ дан jlhoward 16 August 2018 в 04:37
поделиться
  • 1
    Благодарю. Я ценю объяснение того, как эта странность происходит с петлями и ggplot. Теперь я понимаю. Я думал, что это может быть что-то вроде этого - я попытался найти команду, которая нарисовала бы график как последний шаг каждого цикла (например, просто «g»), но я ничего не пробовал. Ваш код цикла - это то, что мне нужно. – user3799203 10 October 2014 в 02:27

Вы можете сделать это без петли:

df.2 <- melt(df)
gg <- ggplot(df.2, aes(x=topic, y=value))
gg <- gg + geom_violin(position="identity", aes(color=variable), alpha=0.3)
gg

enter image description here [/g0]

2
ответ дан hrbrmstr 16 August 2018 в 04:37
поделиться
  • 1
    Это не дает такой же график, как и у «успешных» OP. потому что скрипки масштабируются по-разному, когда вы создаете два слоя отдельно, когда вы группируете variable. Кроме того, следует, наверное, упомянуть, что для этого потребуется загрузить reshape2. – jlhoward 7 October 2014 в 23:43
  • 2
    Очень элегантно. При таком подходе, если я использую 'scale = "width & quot;" aes, сгруппированная, а не индивидуальная масштабируемая тонкость, о которой упоминает jlhoward, не имеет значения. – user3799203 10 October 2014 в 02:19

Просто избегайте использовать цикл for. Как насчет lapply:

g <- g + lapply(2:ncol(df), function(p) {
  geom_violin(aes(y = df[,p], colour = place[p-1]), alpha = 0.3)
})

EDIT: Это действительно не работает. У меня был p <- 2 в моей рабочей области, прежде чем запускать его, а затем он создал график только с данными Чикаго. Во всяком случае, принцип должен по-прежнему работать (хотя melt, вероятно, лучший вариант):

g <- ggplot(df, aes(x=factor(topic)))
g + lapply(place, function(p) {
  geom_violin(aes_string(y = p), alpha = 0.3, color = which(p==place))
})
2
ответ дан shadow 16 August 2018 в 04:37
поделиться
  • 1
    Вы попробовали это? Если я заменил цикл for OP на это, я получаю: Error in [. Data.frame (df, , p) : object 'p' not found. Если я сначала запустил цикл OP for (который создает переменную p), тогда запустите lapply(...), я получаю тот же результат, что и OP. – jlhoward 9 October 2014 в 16:49
  • 2
    Это не сработало для меня. Я получил тот же график, что и у меня с кодом моего плохого цикла. – user3799203 10 October 2014 в 02:37
Другие вопросы по тегам:

Похожие вопросы: