Существует ли «обратная» функция тильды для построения графика в R - PullRequest
1 голос
/ 28 марта 2020

Если начальные данные:

[![df = data.frame(AAA=rnorm(1000,1,1),
                BBB=sample(LETTERS,1000,replace=TRUE))
df = droplevels(df\[df$BBB %in% unique(df$BBB)\[1:5\] == TRUE,\])][1]][1] # Not sure how to do this less dumb...
# Just random number of values to 5 random letters

, и в этом случае я использую пакет vioplot для построения графика:

vioplot(AAA~BBB, data = df, side = "right")

Я хотел бы затем построить на стороне = left "все данные , а не , выбранные для каждой записи по оси X. Так что, если бы она рисовала справа значения df $ BBB ==" A ", я бы хотела, чтобы они отображались слева ,! (df $ BBB == "A"). И так далее для каждой буквы.

Также, как примечание, количество уровней по оси X не определено. В идеале я не хотел бы устанавливать какие-либо пакеты.

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

Спасибо за любые help

Мой обходной путь на данный момент (я все еще очень неуклюж с R):

Plotting_Vios_T <- function(input_Data) {
  library(vioplot)
  vioplot(AAA~BBB, data = input_Data, side = "right")
  x = list()
  y = list()
  for(idx_class in 1:length(unique(input_Data$BBB))) {
    y_t <- input_Data[!(input_Data$BBB == unique(input_Data$BBB)[idx_class]),"AAA"]
    x_t <- rep(unique(input_Data$BBB)[idx_class], length(y_t))

    x <- c(x,x_t)
    y <- c(y,y_t)
    }
  df <- data.frame(x = as.character(x), y = as.numeric(y))
  vioplot(y~x, data = df, side = "left", add = TRUE)
}

1 Ответ

0 голосов
/ 29 марта 2020

Ваша цель - хорошая идея для целей сравнения!

Однако, похоже, что функция violoplot() не реализует эту опцию - на своей странице документации. Таким образом, ваш подход должен быть способом go, учитывая, что для каждой группы набор записей, удовлетворяющих условию дополнения (т. Е. Все, кроме записей в группе), отличается . Это означает, что вам нужен один другой объект (по одному на группу) для хранения этой информации, и это именно то, что вы делаете.

Тем не менее, ниже приведен фрагмент кода, который вносит следующие улучшения в ваш код:

  • он уменьшает память (поскольку он создает данные для каждой группы дополнений и добавляет блок-график к графику Righttaway - без сохранения его во фрейме данных, содержащем записи для всех групп дополнения)
  • it сокращает время выполнения (поскольку он вычисляет уникальные BBB значения только один раз - до for l oop с использованием table())
  • это более читабельно :)

(обратите внимание, что я не использую функцию violoplot(), потому что я У меня не установлен пакет vioplot, я просто использую функцию boxplot(), но вы сможете расширить ее до своих скриптов)

Тестовые данные для построения

I изменил пример данных, чтобы сделать сюжет, который лучше передает то, что мы Затем, следующим образом:

  • Я сократил количество групп (значения BBB) только до первых 3 букв
  • Для каждой группы я создаю нормальное распределение среднее значение которого равно порядковому значению буквы (т. е. 1, 2 или 3) (это позволяет различать распределение цифры c переменная AAA в каждой группе)

-

# The data to plot
set.seed(117)
groups = LETTERS[1:3]
df = data.frame(BBB=sample(groups,1000,replace=TRUE))
df_sp = split(df, df$BBB)
df_sp = lapply(df_sp, transform, AAA = rnorm(length(BBB), mean=as.numeric(BBB), sd=0.2))
df = unsplit(df_sp, df$BBB)
head(df)  

  BBB       AAA
1   C 2.7884212
2   A 0.7924213
3   B 2.0032205
4   B 2.2402493
5   C 3.0513685
6   A 1.2553530

Пример графика

Сначала мы генерируем блокпосты по группам (ваш «правый» план скрипки), а затем добавляем блокпосты дополнения каждой группы (ваш «левый» план скрипки) ).

# Groups to plot
groups = names(table(df$BBB))

# Reduce margins to make plot bigger
op = par(mar=c(5.1,4.1,0.1,0.1))

# Generate the boxplots by group (this would be your "right" violin plots)
boxplot(AAA ~ BBB, data=df, at=(1:length(groups)), boxwex=0.2)

# Add the distribution of the complement (this would be your "left" violin plots)
grp_idx = 0   # This variable is used to define the X location to add the boxplot to.
              # You would also need it in the violoplot() function for the 'at=' parameter
for (grp in groups) {
  grp_idx = grp_idx + 1

  # Complement data to plot for the group
  df_complement = df[ df$BBB!=grp, ]
  df_complement$BBB = grp

  # The 'at' parameter indicates the correct X location to add the boxplot to
  # which is shifted a little bit (by +0.2) to avoid overlap with the boxplot of the group
  boxplot(AAA ~ BBB, data=df_complement, col="red", add=TRUE, at=grp_idx+0.2, boxwex=0.2)
}

# Restore margins
par(op)

Обратите внимание, что нам , а не нужно предварительно рассчитать диапазон оси Y, чтобы каждый add ed бокс-график вписывался в базовые блок-графики по графу группы, потому что этот оригинальный блок-график уже покрывает ВСЕ диапазон оси Y, присутствующий в данных, - поскольку он отображает ВСЕ данные.

Приведенный выше код выдает:

Boxplots by group and their complements

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...