在 R 中使用多个观察值从长到宽转换

Posted

技术标签:

【中文标题】在 R 中使用多个观察值从长到宽转换【英文标题】:Transformation from long to wide with multiple observations in R 【发布时间】:2022-01-20 03:18:36 【问题描述】:

我想将一个数据集从长转换为宽。 数据包含每个时间点的多个观测值。

为了说明,请考虑以下两个示例。

在下面的示例 1 中,数据不包含多个观察结果,并且可以从长转换为宽。

在下面的示例 2 中,数据确实包含多个观察结果(每个时间点 n=3)并且无法从长转换为宽,使用 dcastpivot_wider 进行测试。 p>

谁能建议一种将示例 2 中的测试数据转换为有效格式的方法?

重现问题的代码:

library(ggplot2)
library(ggcorrplot)
library(reshape2)
library(tidyr)
library(data.table)

# EXAMPLE 1 (does work)
# Test data
set.seed(5)
time    <- rep(c(0,10), 1, each = 2)
feature <- rep(c("feat1", "feat2"), 2)
values  <- runif(4, min=0, max=1)

# Concatenate test data
# test has non-unique values in time column
test    <- data.table(time, feature, values)

# Transform data into wide format
test_wide <- dcast(test, time ~ feature, value.var = 'values')

# EXAMPLE 2 (does not work)
# Test data
set.seed(5)
time    <- rep(c(0,10), 2, each = 6)
feature <- c(rep("feat1", 12), rep("feat2", 12))
values  <- runif(24, min=0, max=1)

# Concatenate test data
# test has non-unique values in time column
test    <- data.table(time, feature, values)

# Transform data into wide format
test_wide <- dcast(test, time ~ feature, value.var = 'values')

警告:

Aggregate function missing, defaulting to 'length'

问题:

第一列 (time) 中的非唯一值不会被保留/允许。

# Testing with pivot_wider
test_wider <- pivot_wider(test, names_from = feature, values_from = values)

警告:

Warning message:
Values are not uniquely identified; output will contain list-cols.

问题:

第一列 (time) 中的非唯一值不会被保留/允许。

如果没有更好的主意,可能 输出可能如下所示:

time feat1 feat2
0 0.1046501 0.5279600
0 0.7010575 0.8079352
0 0.2002145 0.9565001

等等

【问题讨论】:

cor(mtcars) 有什么问题? 没什么,这是一个有效的例子,也是我最终想要对测试数据做的事情。但是,我无法将测试数据转换为可用于 cor() 的格式。 (原始mtcars数据集每辆车只有一个观测值。) 我建议使用tidy::pivot_wider,但我真的不知道您期望您的最终输出是什么。如果您专注于开始和结束数据结构并省略有关相关矩阵和mtcars 的内容,您的问题会更清楚。 谢谢!我编辑了问题并修改了示例以使其更加清晰。我还测试了你的建议pivot_wider,由于数据集中的多次观察,它不起作用。 【参考方案1】:

由于存在多个值,因此在转换为宽格式时应如何处理这些值并不明显。这就是您收到警告消息的原因。这是处理它们的一种方式。如果你想要别的东西,那么请给出一个具体的示例输出应该是什么样子

pivot_wider(test, names_from = feature, values_from = values) %>% 
    unnest(c(feat1, feat2))

【讨论】:

请给出您希望在每一行和每一列中出现的确切数字。 另外,我认为您对 test 包含的内容感到困惑。时间和特征之间没有混合。请检查。 感谢您指出这一点,并对造成的混淆感到抱歉。我更正了代码中的部分。 我在原始帖子中添加了一个可能的输出。再次,抱歉之前的混乱。 用你的新例子test,我的解决方案给出了相同形式的东西。 然而,配对值的方式是不明确的。计算相关性可能没有意义,除非您的真实数据已经有顺序。【参考方案2】:

你可能想要这样的东西:

library(dplyr)
test %>% 
  pivot_wider(names_from = c(feature, time), 
              values_from = values)

其中 c(feature, times) 解释了多变量情况。但正如 cmets 中已经指出的那样,如果您想要其他东西,请说明。

【讨论】:

谢谢。测试您的方法会检索 1x2 数据结构,这不是预期的输出。但是,我更新/更正了原始帖子。这可能导致您的答案显示不同的输出。 感谢您的更新。 feat1feat2 彼此完全相同可能会导致问题。 感谢您发现这一点。我在原帖中更正了。该问题的正确解决方案已被接受。

以上是关于在 R 中使用多个观察值从长到宽转换的主要内容,如果未能解决你的问题,请参考以下文章

athena presto - 从长到宽的多列

熊猫从长到宽重塑,由两个变量

tidyR 从长到宽的数据?

从长到宽重塑并创建具有二进制值的列

长到宽R中的多个变量

从长数据帧到宽数组的快速转换