波浪号函数是否有 'inverse' 用于在 R 中绘图

Is there an 'inverse' to the tilde function for plotting in R

如果起始数据是:

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

然后我想在 "side = left" 上绘制所有为每个 x 轴条目选择的数据 而不是 因此,如果它在右侧绘制 df$BBB == "A" 的值,我希望它在左侧绘制 !(df$BBB == "A")。每个字母依此类推。

另请注意,x 轴级别数未定义。理想情况下,我不想安装任何软件包。

我的目标是使用分裂小提琴图突出显示样本人口与剩余人口之间的差异(如果存在)。

感谢您的帮助

我目前的解决方法是(我对 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)
}

您的目标是一个用于比较的好主意!

但是,violoplot() 函数似乎没有实现该选项——根据其文档页面。因此,您的方法应该考虑到,对于每个组,满足补充条件的记录集(即除了组中的记录之外的所有记录)是 不同的 。这意味着您需要一个不同的对象(每组一个)来存储该信息,这正是您所做的。

不过,下面是一段代码,对您的代码进行了以下改进:

  • 减少内存(因为它为每个补充组创建数据并将箱线图添加到图马上——不存储它在包含 all 补充组的记录的数据框中)
  • 减少了执行时间(因为它只计算唯一的BBB值一次——在使用table()for循环之前)
  • 更具可读性 :)

(请注意,我没有使用 violoplot() 函数,因为我没有安装 vioplot 包,我只是使用 boxplot() 函数,但你应该可以将其扩展到您的小提琴情节)

要绘制的测试数据

我更改了示例数据以制作更好地传达我们所追求的情节,如下所示:

  • 我已将组数(BBB 的值)减少到前 3 个字母
  • 对于每个组,我创建一个正态分布,其平均值是字母的序数值(即 1、2 或 3)(这使得每个组中数值变量 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

示例图

首先我们按组生成箱线图(您的 "right" 小提琴图),然后我们添加每个组的补充箱线图(您的 "left" 小提琴图)。

# 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 轴范围以使每个 added 箱线图按组图适合基本箱线图,因为原始箱线图已经涵盖了数据中存在的所有 Y 轴范围——因为它绘制了所有数据。

以上代码产生:

所以你的工作是修改上面的代码以使用 violoplot() 函数。