如何为某种箱线图重组数据框

How to restructure data frame for a certain kind of boxplot

我使用 R 和 Rstudio。我得到了一个纵向数据框,它看起来基本上是这样的:

trait_A_time_1 <- c("2.2","2.9","1.4","3.6")
trait_A_time_2 <- c("4.2","3.2","2.1","4.0")
trait_A_time_3 <- c("2.2","2.5","3.4","1.9")
trait_A_time_4 <- c("3.2","3.9","4.5","4.7")
trait_A_time_5 <- c("2.8","3.3","4.0","1.1")

df <- data.frame(trait_A_time_1, trait_A_time_2, trait_A_time_3, trait_A_time_4, trait_A_time_5)

print (df)

  trait_A_time_1 trait_A_time_2 trait_A_time_3 trait_A_time_4 trait_A_time_5
1            2.2            4.2            2.2            3.2            2.8
2            2.9            3.2            2.5            3.9            3.3
3            1.4            2.1            3.4            4.5            4.0
4            3.6            4.0            1.9            4.7            1.1

它在几周和测量场合测量了人们的某种心理特征。现在我想制作一个如下所示的箱线图:

x axis (groups): the four occasions of measurment
y axis: levels of trait A in the sample

我试过这段代码:

p <- ggplot(data2, aes(x=, y=)) + 
  geom_violin()
p

但它不起作用,因为我没有专门用于场合或 A 级别的变量。我究竟怎样才能得到这些?我必须如何 transpose/restructure 这个数据集才能得到我想要的箱线图?

我添加了一些示例数据。应该这样做

library(tidyverse)

df <- tibble(`trait A time 1` = c(3.3, 2.1, rnorm(10)),
             `trait A time 2` = c(4.1, 2.2, rnorm(10)),
             `trait A time 5` = c(3.9, 1.9, rnorm(10)))

df %>% 
  rename_with(.fn = function(x) gsub('trait A time', "", x)) %>%
  pivot_longer(cols = everything()) %>%
  ggplot(data = .,
         aes(x = name, y = value)) +
  geom_violin() +
  labs(x = "time", y = "trait A")

结果为

您不必像我在这里那样重命名,代码的要点在于 pivot_longer

编辑:

根据要求,我将尝试并简短地解释前两行的作用。 rename_with()dplyr 包中的一个函数,可以重命名列名。它允许多个选项来重命名列,但在这种情况下,我提供了一个函数来重命名所有列的名称。该函数只是将任何列名中的 'trait A time' 替换为空字符 ''。这不是最干净的事情,但它达到了它的目的。

pivot_longer() 是一个非常小众的函数(也来自 dplyr),如果您打算继续使用 R,从现在开始您可能会更频繁地使用它。从本质上讲,它能够将您拥有的数据帧转换为具有更多行的数据帧 --- 使其成为 更长的 数据帧。长数据帧通常是使用 ggplot 进行绘图的方式。它创建一个 name 列和一个 value 列,但这些列的名称也可以更改。请注意,此长数据帧的每一行仅提供 1 个观察的信息,即具有相应名称(在您的情况下为测量时间)及其相应值的观察。之前,你有一个 wider 数据框,其中包含超过 1 个观察的信息,你应该想象如果每行要绘制的信息太多,绘制起来会更难。

df %>% 
  rename_with(.fn = function(x) gsub('trait A time', "", x)) %>%
  pivot_longer(cols = everything()) %>% 
  print()
#> # A tibble: 36 x 2
#>    name   value
#>    <chr>  <dbl>
#>  1 " 1"   3.3  
#>  2 " 2"   4.1  
#>  3 " 5"   3.9  
#>  4 " 1"   2.1  
#>  5 " 2"   2.2  
#>  6 " 5"   1.9  
#>  7 " 1"   0.293
#>  8 " 2"   0.274
#>  9 " 5"  -0.869
#> 10 " 1"   2.30 
#> # ... with 26 more rows