Wizualizacja kombinacji 2 liter

10

Odpowiedzi na to pytanie dotyczące SO zwróciły zestaw około 125 jedno- lub dwuliterowych nazw: /programming/6979630/what-1-2-letter-object-names-conflict-with-existing -r-objects

  [1] "Ad" "am" "ar" "as" "bc" "bd" "bp" "br" "BR" "bs" "by" "c"  "C" 
 [14] "cc" "cd" "ch" "ci" "CJ" "ck" "Cl" "cm" "cn" "cq" "cs" "Cs" "cv"
 [27] "d"  "D"  "dc" "dd" "de" "df" "dg" "dn" "do" "ds" "dt" "e"  "E" 
 [40] "el" "ES" "F"  "FF" "fn" "gc" "gl" "go" "H"  "Hi" "hm" "I"  "ic"
 [53] "id" "ID" "if" "IJ" "Im" "In" "ip" "is" "J"  "lh" "ll" "lm" "lo"
 [66] "Lo" "ls" "lu" "m"  "MH" "mn" "ms" "N"  "nc" "nd" "nn" "ns" "on"
 [79] "Op" "P"  "pa" "pf" "pi" "Pi" "pm" "pp" "ps" "pt" "q"  "qf" "qq"
 [92] "qr" "qt" "r"  "Re" "rf" "rk" "rl" "rm" "rt" "s"  "sc" "sd" "SJ"
[105] "sn" "sp" "ss" "t"  "T"  "te" "tr" "ts" "tt" "tz" "ug" "UG" "UN"
[118] "V"  "VA" "Vd" "vi" "Vo" "w"  "W"  "y"

I kod importowy R:

nms <- c("Ad","am","ar","as","bc","bd","bp","br","BR","bs","by","c","C","cc","cd","ch","ci","CJ","ck","Cl","cm","cn","cq","cs","Cs","cv","d","D","dc","dd","de","df","dg","dn","do","ds","dt","e","E","el","ES","F","FF","fn","gc","gl","go","H","Hi","hm","I","ic","id","ID","if","IJ","Im","In","ip","is","J","lh","ll","lm","lo","Lo","ls","lu","m","MH","mn","ms","N","nc","nd","nn","ns","on","Op","P","pa","pf","pi","Pi","pm","pp","ps","pt","q","qf","qq","qr","qt","r","Re","rf","rk","rl","rm","rt","s","sc","sd","SJ","sn","sp","ss","t","T","te","tr","ts","tt","tz","ug","UG","UN","V","VA","Vd","vi","Vo","w","W","y")

Ponieważ chodziło o wymyślenie niezapomnianej listy nazw obiektów, których należy unikać, a większość ludzi nie jest tak dobra w zrozumieniu solidnego bloku tekstu, chciałbym to sobie wyobrazić.

Niestety nie jestem do końca pewien, jak to najlepiej zrobić. Myślałem o czymś w rodzaju wykresu łodygi i liścia, tylko dlatego, że nie ma powtarzalnych wartości, każdy „liść” został umieszczony w odpowiedniej kolumnie, a nie pozostawiony jako uzasadniony. Lub adaptacja w stylu chmury słów, w której litery są sortowane zgodnie z ich rozpowszechnieniem.

W jaki sposób można to najlepiej i najwyraźniej wizualizować?

Wizualizacje spełniające którekolwiek z poniższych kryteriów są zgodne z duchem tego pytania:

  • Główny cel: Zwiększenie zdolności zapamiętywania zestawu nazw poprzez ujawnienie wzorców w danych

  • Alternatywny cel: Podkreśl interesujące cechy zestawu nazw (np. Które pomagają zwizualizować rozkład, najczęściej używane litery itp.)

Preferowane są odpowiedzi w języku R, ale mile widziane są wszystkie ciekawe pomysły.

Ignorowanie nazw jednoliterowych jest dozwolone, ponieważ łatwiej je podać jako osobną listę.

Ari B. Friedman
źródło

Odpowiedzi:

12

Oto początek: wizualizuj je na siatce pierwszych i drugich liter:

combi <- c("Ad", "am", "ar", "as", "bc", "bd", "bp", "br", "BR", "bs", 
"by", "c",  "C",  "cc", "cd", "ch", "ci", "CJ", "ck", "Cl", "cm", "cn", 
"cq", "cs", "Cs", "cv", "d",  "D",  "dc", "dd", "de", "df", "dg", "dn", 
"do", "ds", "dt", "e",  "E",  "el", "ES", "F",  "FF", "fn", "gc", "gl", 
"go", "H",  "Hi", "hm", "I",  "ic", "id", "ID", "if", "IJ", "Im", "In", 
"ip", "is", "J",  "lh", "ll", "lm", "lo", "Lo", "ls", "lu", "m",  "MH", 
"mn", "ms", "N",  "nc", "nd", "nn", "ns", "on", "Op", "P",  "pa", "pf", 
"pi", "Pi", "pm", "pp", "ps", "pt", "q",  "qf", "qq", "qr", "qt", "r",  
"Re", "rf", "rk", "rl", "rm", "rt", "s",  "sc", "sd", "SJ", "sn", "sp", 
"ss", "t",  "T",  "te", "tr", "ts", "tt", "tz", "ug", "UG", "UN", "V",  
"VA", "Vd", "vi", "Vo", "w",  "W",  "y")

df <- data.frame (first = factor (gsub ("^(.).", "\\1", combi), 
                                  levels = c (LETTERS, letters)),
                  second = factor (gsub ("^.", "", combi), 
                                  levels = c (LETTERS, letters)),
                  combi = combi))

library(ggplot2)
ggplot (data = df, aes (x = first, y = second)) + 
   geom_text (aes (label = combi), size = 3) + 
   ## geom_point () +
   geom_vline (x = 26.5, col = "grey") + 
   geom_hline (y = 26.5, col = "grey")

(był dwie litery:) siatka z literami

ggplot (data = df, aes (x = second)) + geom_histogram ()

drugi list

ggplot (data = df, aes (x = first)) + geom_histogram ()

pierwsza litera

Zbieram:

  • nazw jednoliterowych,

    • Na szczęście i, j, k, i lsą dostępne (tak mogę wskaźnik do tablic 4d)
    • niestety t(czas), c(koncentracja) zniknęły. Podobnie są m(masa), V(objętość) i F(siła). Bez promienia ri średnicy d.
    • Mogę mieć ciśnienie ( p), ilość substancji ( n) i długość l.
    • Może będę musiał zmienić na greckie imiona: εjest OK, ale nie powinno

      π <- pi

      ?

  • Mogę mieć dowolne lowerUPPERimię.

  • Ogólnie rzecz biorąc, rozpoczęcie od dużej litery jest bezpieczniejszym wyborem niż małe litery.

  • nie zaczynaj od clubd

cbeleites
źródło
Dobry początek. Może dodaj linie kwadrantu (w dużym +) przez wykres 2d, aby lepiej zrozumieć, gdzie idą wielkie / małe litery?
Ari B. Friedman,
Myślałem, że to zrobiłem. Tak czy inaczej, oto jest. @ gsk3: dzięki za przesłanie zdjęć!
cbeleites niezadowoleni z SX
Miły. Przeciwnie, dziękuję za udzielenie interesującej odpowiedzi na monit nr 2. :-)
Ari B. Friedman,
Patrząc na wykres 2d, inną sugestią może być zmniejszenie go do siatki 27x26 i zmiana symboli lub kolorów (lub fluktuacji alfa), jeśli dana litera ma dolną / górną / obie. Może również sprawić, że wiersz NA będzie miał inny kolor, aby wizualnie go rozdzielić.
Ari B. Friedman,
1
Zanim opublikowałem odpowiedź, rzuciłem okiem na 27 x 26 (z kolorem i kształtem według pierwszej i drugiej litery wielkimi literami). Ale to nie przekazało łatwej wiadomości, więc natychmiast wróciłem po większą siatkę.
cbeleites niezadowoleni z SX
8

Ok, oto moje bardzo szybkie spojrzenie na wizualizację podobną do „układu okresowego”, opartą na pytaniu SO i komentarzach innych. Głównym problemem jest duża różnica w liczbie zmiennych między pakietami, która utrudnia wizualizację ... Zdaję sobie sprawę, że jest to bardzo zgrubne, więc możesz ją dowolnie zmieniać.

Oto aktualne wyjście (z mojej listy pakietów) Przykładowa fabuła

I kod

# Load all the installed packages
lapply(rownames(installed.packages()), require, 
       character.only = TRUE)
# Find variables of length 1 or 2
one_or_two <- unique(apropos("^[a-zA-Z]{1,2}$"))
# Find which package they come from
packages <- lapply(one_or_two, find)
# Some of the variables may belong to multiple packages, so determine the length 
# of each entry in packages and duplicate the names accordingly
lengths <- unlist(lapply(packages, length))
var.data <- data.frame(var = rep(one_or_two, lengths), 
                   package = unlist(packages))

Teraz mamy taką ramkę danych:

> head(var.data, 10)
   var           package
1   ar     package:stats
2   as   package:methods
3   BD    package:fields
4   bs      package:VGAM
5   bs   package:splines
6   by      package:base
7    c      package:base
8    C     package:stats
9   cm package:grDevices
10   D     package:stats

Możemy teraz podzielić dane według pakietów

 data.split <- split(var.data, var.data$package)

Widzimy, że większość zmiennych pochodzi z pakietu podstawowego i pakietu statystyk

> unlist(lapply(data.split, nrow))
     package:base  package:datasets    package:fields 
               16                 1                 2 
  package:ggplot2 package:grDevices  package:gWidgets 
                2                 1                 1 
  package:lattice      package:MASS    package:Matrix 
                1                 1                 3 
  package:methods      package:mgcv      package:plyr 
                3                 2                 1 
     package:spam   package:splines     package:stats 
                1                 2                14 
 package:survival     package:utils      package:VGAM 
                1                 2                 4 

Wreszcie procedura rysowania

plot(0, 0, "n", xlim=c(0, 100), ylim=c(0, 120), 
     xaxt="n", yaxt="n", xlab="", ylab="")

side.len.x <- 100 / length(data.split)
side.len.y <- 100 / max(unlist(lapply(data.split, nrow)))
colors <- rainbow(length(data.split), start=0.2, end=0.6)    

for (xcnt in 1:length(data.split))
    {
    posx <- side.len.x * (xcnt-1)

    # Remove "package :" in front of the package name
    pkg <- unlist(strsplit(as.character(data.split[[xcnt]]$package[1]), ":"))
    pkg <- pkg[2]

    # Write the package name
    text(posx + side.len.x/2, 102, pkg, srt=90, cex=0.95, adj=c(0, 0))

    for (ycnt in 1:nrow(data.split[[xcnt]]))
        {
        posy <- side.len.y * (ycnt-1)
        rect(posx, posy, posx+side.len.x*0.85, posy+side.len.y*0.9, col = colors[xcnt])
        text(posx+side.len.x/2, posy+side.len.y/2, data.split[[xcnt]]$var[ycnt], cex=0.7)
        }
    }
Nico
źródło
1
Miły! Jednym z interesujących sposobów jest pogrupowanie ich według kategorii (np. Pakiety graficzne, praktyki manipulacji danymi itp.), Kodowanie ich kolorami, a następnie nadanie ogólnemu kształtowi kształtu bardziej przypominającego pudełko niż histogram.
Ari B. Friedman,
+1 Co za przyjemność! :) Bardzo dobra robota. Wydaje mi się, że jedyną rzeczą, która byłaby konieczna do uzyskania funkcjonalności układu okresowego, jest układ tabeli. Standardowy PT ma 2 siatki, z niektórymi elementami brakującymi w górnej 1, a grupy są podzielone / uporządkowane (w przeciwieństwie do 1 grupy = 1 pionowa kolumna). Szczerze mówiąc, nie jest to część, która moim zdaniem będzie trudna. Kolorystyka i układ bloków to część, która najbardziej mnie podnieca i wspaniale jest zobaczyć kod ggplot2.
Iterator,
Potrzebuję kawy. Widzę, że gsk3 miał ten sam komentarz z mniejszą liczbą słów. :) Myślę, że byłem zahipnotyzowany kolorem.
Iterator
1
@Iterator: zwróć uwagę, że są to wszystkie standardowe funkcje wykresu R, bez udziału ggplot2 :)
nico
Święta makrela. Masz rację! Jeszcze bardziej imponujące. Mój wniosek: Ieeeeeeed coffeeeeeeeeeee.
Iterator,
4

Oto histogram oparty na literze. Rozważano zmianę pierwszych liter według numeru, ale odmówiono, ponieważ jest to już zakodowane w elemencie pionowym.

# "Load" data
nms <- c("Ad","am","ar","as","bc","bd","bp","br","BR","bs","by","c","C","cc","cd","ch","ci","CJ","ck","Cl","cm","cn","cq","cs","Cs","cv","d","D","dc","dd","de","df","dg","dn","do","ds","dt","e","E","el","ES","F","FF","fn","gc","gl","go","H","Hi","hm","I","ic","id","ID","if","IJ","Im","In","ip","is","J","lh","ll","lm","lo","Lo","ls","lu","m","MH","mn","ms","N","nc","nd","nn","ns","on","Op","P","pa","pf","pi","Pi","pm","pp","ps","pt","q","qf","qq","qr","qt","r","Re","rf","rk","rl","rm","rt","s","sc","sd","SJ","sn","sp","ss","t","T","te","tr","ts","tt","tz","ug","UG","UN","V","VA","Vd","vi","Vo","w","W","y") #all names
two_in_base <- c("ar", "as", "by", "cm", "de", "df", "dt", "el", "gc", "gl", "if", "Im", "is", "lh", "lm", "ls", "pf", "pi", "pt", "qf", "qr", "qt", "Re", "rf", "rm", "rt", "sd", "ts", "vi") # 2-letter names in base R
vowels <- c("a","e","i","o","u")
vowels <- c( vowels, toupper(vowels) )

# Constants
yoffset.singles <- 3

# Define a function to give us consistent X coordinates
returnX <- function(vec) {
  sapply(vec, function(x) seq(length(all.letters))[ x == all.letters ] )
}

# Make df of 2-letter names
combi <- nms[ sapply( nms, function(x) nchar(x)==2 ) ]
combidf <- data.frame( first = substr(combi,1,1), second=substr(combi,2,2) )
library(plyr)
combidf <- arrange(combidf,first,second)

# Add vowels
combidf$first.vwl <- (combidf$first %in% vowels)
combidf$second.vwl <- (combidf$second %in% vowels)

# Flag items only in base R
combidf$in_base <- paste(combidf$first,combidf$second,sep="") %in% two_in_base

# Create a data.frame to hold our plotting information for the first letters
combilist <- dlply(combidf,.(first),function(x) x$second)
combi.first <- data.frame( first = names(combilist), n = sapply(combilist,length) ,stringsAsFactors=FALSE )
combi.first$y <- 0
all.letters <-  c(letters,LETTERS) # arrange(combi.first,desc(n))$first to go in order of prevalence (which may break the one-letter name display)
combi.first$x <- returnX( combi.first$first )

# Create a data.frame to hold plotting information for the second letters
combidf$x <- returnX( combidf$first )
combidf$y <- unlist( by( combidf$second, combidf$first, seq_along ) )

# Make df of 1-letter names
sngldf <- data.frame( sngl = nms[ sapply( nms, function(x) nchar(x)==1 ) ] )
singles.y <- max(combidf$y) + yoffset.singles
sngldf$y <- singles.y
sngldf$x <- returnX( sngldf$sngl )

# Plot
library(ggplot2)
ggplot(data=combidf, aes(x=x,y=y) ) +
  geom_text(aes( label=second, size=3, colour=combidf$in_base ), position=position_jitter(w=0,h=.25)) +
  geom_text( data=combi.first, aes( label=first, x=x, y=y, size=4 ) ) +
  geom_text( data=sngldf, aes( label=sngl, x=x, y=y, size=4 ) ) +
  scale_size(name="Order (2-letter names)",limits=c(1,4),breaks=c(1,2),labels=c("Second","First")) +
  scale_x_continuous("",breaks=c(13,39),labels=c("lower","UPPER")) +
  scale_y_continuous("",breaks=c(0,5,singles.y),labels=c("First letter of two-letter names","Second letter of two-letter names","One-letter names") ) +
  coord_equal(1.5) +
  labs( colour="In base R" )

wersja z jedno- i dwuliterowymi nazwami na tej samej działce

histogram oparty na literach

Ari B. Friedman
źródło
2

Układ okresowy dla 100, Alex. Jednak nie mam na to kodu. :(

Można by pomyśleć, że pakiet „układu okresowego” może już istnieć w CRAN. Pomysł na schemat kolorystyczny i układ takich danych może być interesujący i użyteczny.

Można je pokolorować według paczki i posortować pionowo według częstotliwości, np. W próbce kodu w CRAN lub tak, jak pojawiają się w lokalnej bazie kodu.

Iterator
źródło
Nie jestem pewien, czy podążę za tobą ... czy mógłbyś zrobić prosty szkic tego, o czym myślisz? Nie wiem, jak mógłby pomóc układ okresowy ...
nico
@nico: Mam na myśli coś takiego: en.wikipedia.org/wiki/Periodic_table Załóżmy, że zastępujemy „elementy nobla” podstawowymi poleceniami R. Halogeny mogą być zastąpione własnymi pakietami i tak dalej. W przypadku takiego pakietu wizualizacji pozostawiłbym użytkownikowi określenie rodzaju wierszy, kolumn, grup i kolorów. Powinno to być dość proste do wdrożenia, choć zrobiłbym to bardzo brutalnie. Umieszczenie byłoby takie, aby przedmioty w tej samej grupie (tj. Paczka) były blisko siebie. Położenie pionowe można określić na podstawie częstotliwości użytkowania.
Iterator,
Ok, teraz rozumiem! Może postaram się sprawdzić, czy mogę coś wymyślić, ale najpierw muszę znaleźć trochę wolnego czasu ... :(
nico
Jeszcze go nie widzę, ale jestem podekscytowany, aby zobaczyć, w co ten pomysł się zmienia :-)
Ari B. Friedman,
1
spojrzał na stackexchange: Tal Galili zapytał o PSE jakiś czas temu, więc nie zapytałem. Ale właśnie wrzuciłem pierwszy kawałek kodu do r-forge: pse.R proszę umieścić gwiazdy przy kasie - nie wiem, jak im uciec, aby zniknęły ...
cbeleites niezadowoleni z SX
1

Dwie pierwsze strony w rozdziale 2 ITILA MacKaya zawierają ładne diagramy pokazujące warunkowe prawdopodobieństwa wszystkich par znaków w języku angielskim. Może się przydać.

Wstyd mi, że nie pamiętam, jakiego programu użyto do ich wytworzenia.

jcb
źródło
1
To fajne, ale wydaje mi się, że wszystkie zależą od dodatkowych informacji (rozpowszechnienia) związanych z każdą parą liter i liter. Tak więc rysuje 3 wymiary, podczas gdy my głównie 2. Chciałbym jednak mieć informacje o występowaniu dla R. Ale to operacja eksploracji danych na kolejny dzień.
Ari B. Friedman,