Ggplot'ta sütun adını belirtmek için bir değişken nasıl kullanılır


110

Bir ggplot komutum var

ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )

bir işlevin içinde. Ancak, renk ve grup olarak kullanılacak sütunu seçmek için işlevin bir parametresini kullanabilmek istiyorum. Yani böyle bir şey isterdim

f <- function( column ) {
    ...
    ggplot( rates.by.groups, aes(x=name, y=rate, colour= ??? , group=??? ) )
}

Böylece ggplot'ta kullanılan sütun parametre tarafından belirlenir. Örneğin f ("majr") için şu etkiyi elde ederiz:

ggplot( rates.by.groups, aes(x=name, y=rate, colour=majr, group=majr) )

ama f ("cinsiyet") için şu etkiyi alıyoruz:

  ggplot( rates.by.groups, aes(x=name, y=rate, colour=gender, group=gender) )

Denediğim bazı şeyler:

ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ) )

işe yaramadı. Ne de yapmadı

e <- environment() 
ggplot( rates.by.groups, aes(x=name, y=rate, colour= columnName , group=columnName ), environment=e )

Yanıtlar:


166

Şunları kullanabilirsiniz aes_string:

f <- function( column ) {
    ...
    ggplot( rates.by.groups, aes_string(x="name", y="rate", colour= column,
                                        group=column ) )
}

Sütunu işleve bir dize olarak ( f("majr")yerine f(majr)) ilettiğiniz sürece . Ayrıca diğer sütunları "name"ve "rate"dizeleri olarak değiştirdiğimizi unutmayın .

Herhangi bir nedenle kullanmamayı tercih aes_stringederseniz, bunu şu şekilde değiştirebilirsiniz (biraz daha hantal):

    ggplot( rates.by.groups, aes(x=name, y=rate, colour= get(column),
                                        group=get(column) ) )

Yapmamalısın / yapamamalısın aes_string(x = rates.by.groups$name...ve yine de ggplot(data = rates.by.groups...tartışmayı zaten geçtiğin için buna ihtiyacın yok . ( Bu sorudaki sorun )
smci

5
İnsanları Moody_Mudskipper'ın ggplot2 sürüm 3.0.0 güncellemeleri ile ilgili yanıtına yönlendirmek için bir not ekledik
Gregor Thomas

@buncis Bu doğru değil, alıntı yapmak "column_name"ya "column"da işe yaramaz
David Robinson

@DavidRobinson, hatam özür dilerim, kodun parametresi olan bir fonksiyona sarıldığını görmüyorum,
yorumumu

"hantal"? R'deki standart dışı değerlendirme, ironik bir şekilde bir programlama dilinde şimdiye kadar karşılaştığım en hantal "özellik" tir. Gerçekten çıldırtıcı.
jessexknight

48

Gönderen sürüm notları arasında ggplot2 V3.0.0:

aes () artık, !!, !!!, ve: =. Bu, artık kullanımdan kaldırılmış (ancak uzun süre kalacaktır) aes_ () ve aes_string () 'nin yerini alır.

Şimdi deyimsel yol, değişkenin içerdiği dizeyi sym()(temel takma adlar as.name()/ ile neredeyse aynıdır) kullanarak bir sembole dönüştürmek as.symbol()ve!!

OP'nin verilerini simüle ederek yapabileceğimiz:

library(tidyverse)
rates.by.groups <- data.frame(
  name = LETTERS[1:3],
  rate = 1:3,
  mjr = LETTERS[c(4,4,5)],
  gender = c("M","F","F")
)

f <- function(column) {
  column <- sym(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

f("gender")
f("mjr")
x <- "gender"
f(x)

İşleve ham isimler vermeyi tercih edersek yapabileceğimiz:

f2 <- function(column) {
  column <- ensym(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

Adlarla ve sembollerle VE dize değişmezleriyle çalışacaktır.

f2(gender)
f2(mjr)
f2("gender")
f2("mjr")

Lionel'in dediği gibi ensym():

LHS'de her ikisini de sağlayabileceğiniz bağımsız değişkenlerin sözdizimini taklit etmesi amaçlanmıştır, örneğin liste (çıplak = 1, "tırnaklı" = 2)


Üzerine bir not enquo()

enquo()argümana beslenen ifadeyi (mutlaka bir sembol değil) tırnak içine alır, bir dizgeyi değişmez bir sembole dönüştürmez ensym(), yani burada daha az uyarlanabilir, ancak yapabiliriz:

f3 <- function(column) {
  column <- enquo(column)
  ggplot(rates.by.groups, 
         aes(x = name, 
             y = rate, 
             fill  = !!column, 
             group = !!column)) +
    geom_col()
}

f3(gender)
f2(mjr)

14
Bu derli toplu şeyler çok can sıkıcı. Belgelerin aes()kendisi hakkında konuşuyor enquo()ama işe yaramıyor. Ve daha ensym()önce kim duydu ? BÜYÜK
GÖRÜŞ

@Moody_Mudskipper f2Dört örneğin hepsi işe yarıyor ve sütun adını bir değişkende (yani aname <- "mjr"; f2(aname)) yakalamak da işe yarıyor . Veri çerçevesini kullanarak işlemek için kod eklersem, dplyrdeğişken adındaki dizeyi değil, değişken adını kullanarak bir sütun bulmaya çalışır. Başka bir deyişle, rates.by.groups %>% group_by(!!column)...işe nasıl başlayabilirim ve hala arama yapmanın üç yolunu nasıl destekleyebilirim f2?
steveb

1
"bir değişkendeki sütun adını yakalamak da öyle": başarısız olmaz, ancak aynı sonucu döndürmez, ensymad olarak sağlanan argümanları ele almak ve bunların etrafındaki alıntıları tolere etmek için tasarlanmıştır. Argümanı bir ad olarak ele almak ve ad bulunamazsa değere geri dönmek istediğinize inanıyorum. Aslında olan şey bu select, ama bununla değil group_by... Etrafından dolaşmak mümkün ama açık değil. Sizin için önemliyse, kendi sorusunu hak edeceğini düşünüyorum.
Moody_Mudskipper

@Moody_Mudskipper Teşekkürler. İkisini de kullanıyordum selectve group_bybu yüzden büyük olasılıkla sorun buydu. Yeni bir soru oluşturabilirim, ancak basit bir örnek bulmam ve cevaplanıp cevaplanmadığını kontrol etmem gerekiyor. Değilse gönderebilirim.
steveb

1
Nasıl kullanılır !! durumunda facet_grid? facet_grid(cols = vars(!!column))facet_grid(~ !!column)
İle

15

aes_stringBunun yerine kullanmayı deneyin aes.


5
Bu harika bir tavsiye ama onlara nedenini söyleyebilir misin? aes_string, değişken olmayanlar için "" kullanmanızı sağlar ve değişkenleri tırnaksız olarak kullanırsınız. aes_string (x = "foo", y = "ücret", grup = değişken)
mtelesha

@mtelesha belki de değişkenin değeri dizge olduğu içindir
buncis

12

Diğer bir seçenek ( ggplot2 > 3.0.0), .dataseçilen değişkeni / sütunu rates.by.groupsveri çerçevesinden dilimlemek için düzenli değerlendirme zamirini kullanmaktır .

library(ggplot2)
theme_set(theme_classic(base_size = 14))

# created by @Moody_Mudskipper
rates.by.groups <- data.frame(
  name = LETTERS[1:3],
  rate = 1:3,
  mjr = LETTERS[c(4, 4, 5)],
  gender = c("M", "F", "F")
)

f1 <- function(df, column) {
  gg <- ggplot(df, 
         aes(x = name, 
             y = rate, 
             fill  = .data[[column]], 
             group = .data[[column]])) +
    geom_col() +
    labs(fill = column)
  return(gg)
}

plot_list <- lapply(list("gender", "mjr"), function(x){ f1(rates.by.groups, x) })
plot_list
#> [[1]]

#> 
#> [[2]]

# combine all plots
library(egg)
ggarrange(plots = plot_list,
          nrow = 2,
          labels = c('A)', 'B)'))

Reprex paketi (v0.2.1.9000) tarafından 2019-04-04 tarihinde oluşturuldu


1

Kullanmak aes_stringbu sorunu çözer, ancak hata çubukları eklerken bir sorunla karşılaşır geom_errorbar. Aşağıda basit bir çözüm var.

#Identify your variables using the names of your columns indie your dataset
 xaxis   <- "Independent"   
 yaxis   <- "Dependent"
 sd      <- "error"

#Specify error bar range (in 'a-b' not 'a'-'b')
 range   <- c(yaxis, sd)                                #using c(X, y) allows use of quotation marks inside formula
 yerrbar <- aes_string(ymin=paste(range, collapse='-'), 
                       ymax=paste(range, collapse='+'))


#Build the plot
  ggplot(data=Dataset, aes_string(x=xaxis, y=yaxis)) +
    geom_errorbar(mapping=yerrbar, width=15, colour="#73777a", size = 0.5) +
    geom_point   (shape=21)

Bonus, ggplot içindeki şu satırları kullanarak arsanıza yönler de ekleyebilirsiniz:

facet_grid(formula(paste(Variable1, "~", Variable2)))

Bu komut dosyası, bu orijinal gönderiden değiştirildi: ggplot2 - Özel bir işlev kullanan hata çubukları


1

İşte son derece basit bir örnek.

Sadece iki şey yap

  1. Dizeyi bir sembole çevirin
  2. Ekle !!Bunu kullandığınızda
select_col <- sym("Petal.Length")

iris %>% 
  ggplot(aes(x = Sepal.Length, y = !!select_col)) +
  geom_point()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.