Визуализация 2-буквенных комбинаций

10

Ответы на этот вопрос по SO вернули набор из примерно 125 одно- или двухбуквенных имен: /programming/6979630/what-1-2-letter-object-names-conflict-with-existing -r-объекты

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

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

Поскольку суть вопроса заключалась в том, чтобы придумать запоминающийся список имен объектов, которых следует избегать, и большинство людей не очень хорошо разбираются в прочном блоке текста, я хотел бы представить это.

К сожалению, я не совсем уверен, что лучший способ сделать это. Я думал о чем-то похожем на сюжет со стволом и листом, только поскольку повторяющихся значений нет, каждый «лист» был помещен в соответствующий столбец, а не выровнен по левому краю. Или адаптация в стиле wordcloud, в которой буквы измеряются в соответствии с их распространенностью.

Как это может быть наиболее четко и эффективно визуализировано?

Визуализации, которые выполняют одно из следующих действий, соответствуют духу этого вопроса:

  • Основная цель: улучшить запоминаемость набора имен путем выявления закономерностей в данных

  • Альтернативная цель: выделите интересные особенности набора имен (например, которые помогают визуализировать распределение, наиболее распространенные буквы и т. Д.)

Ответы на R предпочтительны, но все интересные идеи приветствуются.

Допускается игнорирование однобуквенных имен, так как их проще всего представить в виде отдельного списка.

Ари Б. Фридман
источник

Ответы:

12

Вот начало: визуализируйте их на сетке из первых и вторых букв:

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

(было: две буквы) сетка с буквами

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

второе письмо

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

первое письмо

Я собираю:

  • из однобуквенных имен,

    • К счастью i, j, kиl доступны (так что может индексировать до 4d массивов)
    • к сожалению t(время), c(концентрация) ушли. Таковы m(масса), V(объем) и F(сила). Нет rни радиуса, ни диаметраd .
    • Я могу иметь давление ( p), количество вещества ( n) и длину l, хотя.
    • Может быть, мне придется изменить на греческие имена: εвсе в порядке, но тогда не должно

      π <- pi

      ?

  • Я могу иметь любое lowerUPPERимя, какое захочу.

  • В общем, начинать с заглавной буквы безопаснее, чем строчной.

  • не начинайте с cилиd

cbeleites
источник
Хорошее начало. Может быть, добавить линии квадранта (в большом +) через 2d график, чтобы лучше понять, куда идут заглавные / строчные буквы?
Ари Б. Фридман
Я думал, что сделал это. В любом случае, вот оно. @ gsk3: спасибо за загрузку картинок!
cbeleites недоволен SX
Ницца. И наоборот, спасибо за интересный ответ на приглашение № 2. :-)
Ари Б. Фридман
Глядя на ваш 2-мерный график, можно предложить еще один вариант: уменьшить его до сетки 27х26 и изменить символы или цвета (или дрожание с альфа-каналом), если у данной буквы есть нижний / верхний / оба. Может также сделать ряд NA другим цветом, чтобы выделить его визуально.
Ари Б. Фридман
1
Перед тем, как опубликовать ответ, я посмотрел на 27 x 26 (цвет и форма соответствуют первой и второй букве в верхнем регистре). Но это не передавало легкого сообщения, поэтому я немедленно вернулся к большей сетке.
cbeleites недоволен SX
8

Хорошо, вот мой очень быстрый взгляд на визуализацию, подобную «периодической таблице», основанную на вопросе SO и комментариях других. Основная проблема заключается в большой разнице в количестве переменных между пакетами, что мешает визуализации ... Я понимаю, что это очень грубо, поэтому, пожалуйста, не стесняйтесь менять ее по своему желанию.

Вот текущий вывод (из моего списка пакетов) Пример сюжета

И код

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

Теперь у нас есть фрейм данных:

> 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

Теперь мы можем разделить данные по пакетам

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

Мы видим, что большинство переменных происходят из пакета base и 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 

Наконец, процедура рисования

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
источник
1
Ницца! Один из интересных способов сделать это - сгруппировать их по категориям (например, графические пакеты, методы манипулирования данными и т. Д.), Кодировать их цветом, а затем сделать общую форму более похожей на прямоугольник, а не на гистограмму.
Ари Б. Фридман
+1 Какое удовольствие! :) Очень хорошая работа. Я предполагаю, что единственное, что было бы необходимо для получения функциональности периодической таблицы, - это макет таблицы. Стандартный PT имеет 2 сетки, в верхней части 1 отсутствуют некоторые элементы, а группы разделены / переставлены (в отличие от 1 группы = 1 вертикальный столбец). Если честно, это не та часть, которую я думал, будет трудно. Раскраска и расположение блоков - это та часть, которая меня больше всего волнует, и здорово видеть код ggplot2.
Итератор
Мне нужен кофе. Я вижу, что у gsk3 был тот же комментарий с меньшим количеством слов. :) Я думаю, что я был загипнотизирован цветом.
Итератор
1
@Iterator: обратите внимание, что это все стандартные функции сюжета R, ggplot2 не задействован :)
nico
Святая скумбрия. Вы правы! Еще более впечатляюще. Мой вывод: я неееееееею кофееееееееееее.
Итератор
4

Вот гистограмма на основе букв. Рассматривал изменение размера первых букв по номерам, но решил отказаться, поскольку он уже закодирован в вертикальном компоненте.

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

версия с одно- и двухбуквенными именами на одном сюжете

буквенная гистограмма

Ари Б. Фридман
источник
2

Периодическая таблица на 100, Алекс. У меня нет кода для этого, хотя. :(

Можно подумать, что пакет «периодической таблицы» уже может существовать в CRAN. Идея схемы раскраски и размещения таких данных может быть интересной и полезной.

Они могут быть раскрашены по пакетам и отсортированы вертикально по частоте, например, в образце кода на CRAN или в том виде, в каком они появляются в локальной кодовой базе.

Итератор
источник
Не уверен, что я пойду за тобой ... не мог бы ты сделать простой набросок того, о чем ты думаешь? Я не вижу, как макет периодической таблицы мог бы помочь здесь ...
Нико
@nico: я думаю о чем-то вроде этого: en.wikipedia.org/wiki/Periodic_table Предположим, что мы заменяем «элементы nobel» на базовые команды R. Галогены могут быть заменены собственным пакетом (-ами) и так далее. С таким пакетом визуализации я бы оставил пользователю возможность определять характер строк, столбцов, групп и цветов. Это должно быть довольно просто реализовать, хотя я бы сделал это очень грубо. Размещение будет таким, что предметы в одной группе (то есть в упаковке) находятся рядом друг с другом. Вертикальное размещение может быть определено частотой использования.
Итератор
Хорошо, теперь я понимаю! Может быть, я попытаюсь выяснить, смогу ли я что-нибудь выпустить, но сначала мне нужно найти немного свободного времени ... :(
nico
Я пока не совсем понимаю, но я рад видеть, во что превращается эта идея :-)
Ари Б. Фридман,
1
Я посмотрел на stackexchange: Тал Галили действительно спрашивал о PSE, поэтому я не спрашивал. Но я просто отправил первый фрагмент кода в r-forge: pse.R, пожалуйста, поставьте звезды вокруг кассы - я не знаю, как избежать их, чтобы они исчезли ...
cbeleites недоволен SX
1

На первых двух страницах второй главы ITILA Маккея есть красивые диаграммы, показывающие условные вероятности всех пар символов в английском языке. Вы можете найти это полезным.

Мне стыдно сказать, что я не помню, какая программа использовалась для их производства.

JCB
источник
1
Это круто, но мне кажется, что все они зависят от наличия некоторой дополнительной информации (распространенности), связанной с каждой парой буква-буква. Таким образом, он отображает 3 измерения, в то время как мы в основном строим график 2 .... Я бы хотел получить информацию о распространенности R. Но это операция по извлечению данных на следующий день.
Ари Б. Фридман