【问题标题】:Using tidyr or similar to make a tall data set wide, while collapsing multiple values into a vector使用 tidyr 或类似的方法使 tall 数据集变宽,同时将多个值折叠成一个向量
【发布时间】:2016-08-03 08:58:42
【问题描述】:

我有一组来自 Matlab 的数据,我想在 R 中使用它。我有一组主题,以及每个主题中的一组条件。在每种情况下,每个受试者都产生了一些数据。我把它写到一个“高”表中,如下所示:

    subject   condition   data
#1  id1       cond1       0.12
#2  id1       cond1       0.43
#3  id1       cond2       1.26
#4  id2       cond1       1.96
#5  id2       cond2       0.24
#6  id2       cond2       0.62
...

如您所见,一个问题是每个主题的每个条件中的值数量不同,主题内的每个条件中的值数量也不相同。我对这些变量在受试者之间的分布感兴趣,所以我希望在“宽”数据框中的列表中保留原始值,如下所示:

    subject   condition   data
#1  id1       cond1       c(0.12, 0.43)
#2  id1       cond2       c(1.26)
#3  id2       cond1       c(1.96)
#4  id2       cond2       c(0.24, 0.62)
...

这样做的最佳方法是什么?我过去使用过 tidyr::spread(),如果没有每行唯一的标识变量,它在这里不起作用,但即使我添加了,我也看不出它是如何工作的。

我也尝试使用 dplyr::group_by(data, subject, condition),但我不知道如何从那里开始。是否可以通过使用 c() 作为汇总函数来汇总分组表...?这对我不起作用。

一如既往,感谢您的帮助!

【问题讨论】:

  • 当您拥有相同数量的列时,您的数据不会从高变为宽 - 宽度(列数)是恒定的!您只是在汇总 - 将现有行汇总为一行。
  • 我不太确定您想要的表示将如何有用。常见的习惯用法是dplyr::group_by 然后dplyr::summarize() 做任何你想做的事情来查看“这些变量在受试者之间的分布”。请告诉我们您的最终目标,而不仅仅是您认为必要的中间步骤(但这实际上可能会使一个简单的问题过于复杂)..
  • 我们想避免XY Problems
  • 嗨 Gregor,非常感谢 cmets!我明白你的意思——我确实问过如何实现我想要的,而不是陈述我的问题。最终目标是从字面上比较这些变量的分布 - 所以我想绘制 cond 的直方图。 1 和 2 在一个受试者内,拟合曲线,并比较这些曲线的参数。在进行主题内比较之后,我还将继续通过将数据拟合到组聚合来进行主题间比较,但我认为首先将它们全部放入一个整洁的数据框中是最容易的。
  • PS:我应该补充一点,我发布的示例被过度简化了,每个主题大约有 50 个值!

标签: r dplyr tidyr


【解决方案1】:
library(dplyr)
library(tidyr)

data = 
"subject   condition   data
id1       cond1       0.12
id1       cond1       0.43
id1       cond2       1.26
id2       cond1       1.96
id2       cond2       0.24
id2       cond2       0.62" %>%
  read.table(text = ., header = TRUE)

对于宽格式:

wide_form = 
  data %>%
  group_by(subject, condition) %>%
  mutate(order = 1:n() %>% paste0("value", .)) %>%
  spread(order, data)

对于嵌套形式:

nested_form = 
  data %>%
  group_by(subject, condition) %>%
  summarize(data = data %>% list)

【讨论】:

    【解决方案2】:

    您可以使用aggregate() 创建由数字向量组成的listdata

    aggregate(data ~ subject + condition, FUN = list, data = df)
    #  subject condition       data
    #1     id1     cond1 0.12, 0.43
    #2     id2     cond1       1.96
    #3     id1     cond2       1.26
    #4     id2     cond2 0.24, 0.62
    

    【讨论】:

    • 谢谢 - 这工作!就像格雷戈尔在最初的问题下所说的那样,我混淆了我的术语。我并不是真的在寻找一种让它更宽的方法。但是使用您的解决方案,这也很容易:wideData <- df %>% aggregate(data ~ subject + condition, FUN = list, .) %>% spread(condition, data)
    猜你喜欢
    • 2019-02-05
    • 2017-11-10
    • 1970-01-01
    • 2020-09-23
    • 2019-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-23
    相关资源
    最近更新 更多