Visualizando combinações de 2 letras

10

As respostas a esta pergunta no SO retornaram um conjunto de aproximadamente 125 nomes de uma a duas letras: /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"

E código de importação 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")

Como o objetivo da pergunta era apresentar uma lista memorável de nomes de objetos a serem evitados, e a maioria dos humanos não é tão boa em entender um bloco de texto sólido, eu gostaria de visualizar isso.

Infelizmente, não estou exatamente certo da melhor maneira de fazer isso. Eu tinha pensado em algo como um gráfico de caule e folhas, apenas porque não há valores repetidos cada "folha" foi colocada na coluna apropriada em vez de ser justificada. Ou uma adaptação no estilo wordcloud, onde as letras são dimensionadas de acordo com sua prevalência.

Como isso pode ser visualizado de maneira mais clara e eficiente?

As visualizações que seguem um dos seguintes se enquadram no espírito desta pergunta:

  • Objetivo principal: aprimorar a memorização do conjunto de nomes, revelando padrões nos dados

  • Objetivo alternativo: destacar recursos interessantes do conjunto de nomes (por exemplo, que ajudam a visualizar a distribuição, as letras mais comuns etc.)

As respostas em R são preferidas, mas todas as idéias interessantes são bem-vindas.

É permitido ignorar os nomes de uma letra, pois esses são mais fáceis de fornecer como uma lista separada.

Ari B. Friedman
fonte

Respostas:

12

Aqui está um começo: visualize-os em uma grade da primeira e da segunda letras:

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")

(era duas letras:) grade com letras

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

segunda letra

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

primeira carta

Eu recolho:

  • dos nomes de uma letra,

    • Felizmente i, j, k, e lestão disponíveis (por isso pode indexar-se a matrizes 4d)
    • infelizmente t(tempo), c(concentração) se foram. O mesmo acontece com m(massa), V(volume) e F(força). Sem raio rnem diâmetro d.
    • Mas posso ter pressão ( p), quantidade de substância ( n) e comprimento l.
    • Talvez eu precise mudar para nomes gregos: εestá tudo bem, mas não deveria

      π <- pi

      ?

  • Eu posso ter o lowerUPPERnome que quiser.

  • Em geral, começar com uma letra maiúscula é uma aposta mais segura que uma minúscula.

  • não comece com coud

cbeleites
fonte
Bom começo. Talvez adicione linhas do quadrante (em um grande +) através da plotagem 2D para dar uma melhor noção de onde as letras maiúsculas / minúsculas vão?
Ari B. Friedman
Pensei que fiz isso. Enfim, aqui está. @ gsk3: obrigado por enviar as fotos!
cbeleites descontente com SX 08/08
Agradável. E, pelo contrário, obrigado por fornecer uma resposta interessante ao prompt # 2. :-)
Ari B. Friedman
Olhando para o seu gráfico 2D, outra sugestão pode ser reduzi-lo a uma grade 27x26 e alterar símbolos ou cores (ou instabilidade com alfa) se uma determinada letra tiver menor / maior / ambos. Também poderia tornar a linha de NA uma cor diferente para separá-la visualmente.
Ari B. Friedman
11
Eu dei uma olhada em 27 x 26 antes de postar a resposta (com cor e forma de acordo com a primeira e a segunda letra em maiúsculas). Mas isso não transmitiu uma mensagem fácil, então voltei imediatamente para a grade maior.
Cbeleites infeliz com SX 08/08
8

Ok, aqui está minha rápida visão de uma visualização tipo "tabela periódica", com base na pergunta do SO e nos comentários dos outros. O principal problema é a grande diferença no número de variáveis ​​entre pacotes, o que dificulta a visualização ... Percebo que isso é muito difícil, portanto, fique à vontade para alterá-lo como desejar.

Aqui está a saída atual (da minha lista de pacotes) Gráfico de exemplo

E o código

# 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))

Agora, temos um quadro de dados como este:

> 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

Agora podemos dividir os dados por pacote

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

Podemos ver que a maioria das variáveis ​​vem do pacote base e stats

> 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 

Finalmente, a rotina de desenho

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
fonte
11
Agradável! Uma maneira interessante de fazer isso seria agrupá-los por categoria (por exemplo, pacotes de gráficos, práticas de manipulação de dados etc.), codificá-los por cores e tornar a forma geral mais parecida com uma caixa do que com um histograma.
Ari B. Friedman
+1 Que delícia! :) Muito bom trabalho. Eu acho que a única coisa que seria necessária para obter a funcionalidade periódica da tabela é o layout da tabela. O PT padrão possui 2 grades, com alguns elementos ausentes no top 1, e os grupos são divididos / reorganizados (em oposição a 1 grupo = 1 coluna vertical). Para ser sincero, essa não é a parte que pensei que seria difícil. O layout da coloração e do bloco é a parte que mais me excita e é ótimo ver o código ggplot2 para ele.
Iterator
Eu preciso de café. Vejo que o gsk3 teve o mesmo comentário com menos palavras. :) Eu acho que fiquei fascinado pela cor.
Iterator
11
@Iterator: nota que é todas as funções do enredo padrão R, não ggplot2 envolvido :)
nico
Cavala sagrada. Você está certo! Ainda mais impressionante. Minha conclusão: eueeeeeeeeeeeeeeeeeeeeeeeeeee.
Iterator
4

Aqui está um histograma baseado em cartas. Considerado dimensionar as primeiras letras pelo número, mas decidido contra, uma vez que já está codificado no componente vertical.

# "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" )

versão com nomes de uma e duas letras no mesmo gráfico

histograma baseado em letras

Ari B. Friedman
fonte
2

Tabela Periódica para 100, Alex. Eu não tenho código para isso, no entanto. :(

Pode-se pensar que um pacote "tabela periódica" já exista no CRAN. A idéia de um esquema de cores e o layout desses dados podem ser interessantes e úteis.

Eles podem ser coloridos por pacote e classificados verticalmente por frequência, por exemplo, em uma amostra de código no CRAN ou como eles aparecem na base de código local.

Iterador
fonte
Não tenho certeza se eu te sigo ... você poderia fazer um esboço simples do que está pensando? Eu não vejo como um layout de tabela periódica ajudaria aqui ...
nico
@nico: Estou pensando em algo assim: en.wikipedia.org/wiki/Periodic_table Suponha que substituamos "elementos nobel" pelos comandos R básicos. Os halogênios podem ser substituídos pelos próprios pacotes e assim por diante. Com esse pacote de visualização, deixaria ao usuário especificar a natureza das linhas, colunas, grupos e cores. Deve ser uma coisa bastante simples de implementar, embora eu o faça de maneira muito grosseira. O posicionamento seria tal que os itens do mesmo grupo (ou seja, pacote) fiquem próximos um do outro. O posicionamento vertical pode ser determinado pela frequência de uso.
Iterator
OK, agora eu entendo! Talvez eu tente ver se consigo encontrar alguma coisa, mas primeiro preciso encontrar algum tempo livre ... :(
nico
Eu não vejo isso ainda, mas estou animado para ver o que esta ideia se transforma em :-)
Ari B. Friedman
11
deu uma olhada na stackexchange: Tal Galili perguntou sobre a PSE há um tempo atrás, então eu não perguntei. Mas eu só empurrou um primeiro pedaço de código para r-forja: pse.R agradar estrelas colocar em torno do check-out - Eu não sei como escapar deles para que eles desaparecem ...
cbeleites infeliz com SX
1

As duas primeiras páginas do capítulo 2 do ITILA de MacKay têm bons diagramas mostrando as probabilidades condicionais de todos os pares de caracteres no idioma inglês. Você pode achar isso útil.

Tenho vergonha de dizer que não me lembro de qual programa foi usado para produzi-los.

jcb
fonte
11
É legal, mas me parece que todos dependem de ter alguma informação adicional (prevalência) associada a cada par letra-letra. Portanto, ele representa graficamente 3 dimensões, enquanto que representamos principalmente 2 ... Eu adoraria ter as informações de prevalência para R, no entanto. Mas essa é uma operação de mineração de dados para outro dia.
Ari B. Friedman