gpt4 book ai didi

r - 在R中将数据帧从 "wide"格式转换为 "long"格式

转载 作者:行者123 更新时间:2023-12-02 09:57:04 24 4
gpt4 key购买 nike

我有以下数据框:

 df = data.frame(A_1 = c(1,2,3), A_2 = c(4,5,6), A_3 = c(7,8,9), B_1 = c(10, 11, 12), B_2 = c(13, 14, 15), B_3 = c(16, 17, 18))

#> df
# A_1 A_2 A_3 B_1 B_2 B_3
#1 1 4 7 10 13 16
#2 2 5 8 11 14 17
#3 3 6 9 12 15 18

列名称包含字母和数字。该字母指的是特定变量(例如,A 是一个因素,B 是一个因素),而列名称中的数字指的是个人。换句话说,每个个体都有 A 和 B 的值:A_1 和 B_1 是个体 1 的列,A_2、B_2 是个体 2 的列,等等。 p>

我想达到以下结果:请注意,所有“A”列都合并为一个“A”列,“B”列也是如此:

   A  B
# 1 10
# 2 11
# 3 12
# 4 13
# 5 14
# 6 15
# 7 16
# 8 17
# 9 18

有什么简单的方法可以实现这一点吗?请注意,我的真实数据框包含 20 多个不同的字母列(A、B、C...),每个字母都有三个子列(例如:A_1、A_2、A_3)。

谢谢!!

最佳答案

这称为将数据从“宽”格式“ reshape ”为“长”格式。在 R 基础中,一个工具是 reshape ,但您首先需要一个“id”变量:

reshape(df, direction = "long", varying = names(df), sep = "_")
# time A B id
# 1.1 1 1 10 1
# 2.1 1 2 11 2
# 3.1 1 3 12 3
# 1.2 2 4 13 1
# 2.2 2 5 14 2
# 3.2 2 6 15 3
# 1.3 3 7 16 1
# 2.3 3 8 17 2
# 3.3 3 9 18 3

如果需要,您可以删除其他列。

<小时/>

为了好玩,这里有另一种方法,使用“reshape2”包(从原始示例数据开始):

library(reshape2)
dfL <- melt(as.matrix(df))
dfL <- cbind(dfL, colsplit(dfL$Var2, "_", c("Factor", "Individual")))
dcast(dfL, Individual + Var1 ~ Factor, value.var="value")
# Individual Var1 A B
# 1 1 1 1 10
# 2 1 2 2 11
# 3 1 3 3 12
# 4 2 1 4 13
# 5 2 2 5 14
# 6 2 3 6 15
# 7 3 1 7 16
# 8 3 2 8 17
# 9 3 3 9 18
<小时/>

如果您生活在最前沿,“data.table”版本 1.8.11 现在已经实现了“melt”和“dcast”。我还没有玩过太多,但它也非常简单。同样,与我迄今为止提供的所有解决方案一样,需要一个“id”。

library(reshape2)
library(data.table)
packageVersion("data.table") ## Must be at least 1.8.11 to work
# [1] ‘1.8.11’

DT <- data.table(cbind(id = sequence(nrow(df)), df))
DTL <- melt(DT, id.vars="id")
DTL[, c("Fac", "Ind") := colsplit(variable, "_", c("Fac", "Ind"))]
dcast.data.table(DTL, Ind + id ~ Fac)
# Ind id A B
# 1: 1 1 1 10
# 2: 1 2 2 11
# 3: 1 3 3 12
# 4: 2 1 4 13
# 5: 2 2 5 14
# 6: 2 3 6 15
# 7: 3 1 7 16
# 8: 3 2 8 17
# 9: 3 3 9 18
<小时/>

更新

另一个选择是使用 merged.stack来 self 的“splitstackshape”包。如果您还使用as.data.table(df, keep.rownames = TRUE),效果会很好。 ,这将创建相当于 data.table(cbind(id = sequence(nrow(df)), df)) “data.table”方法中的一步。

library(splitstackshape)
merged.stack(as.data.table(df, keep.rownames = TRUE),
var.stubs = c("A", "B"), sep = "_")
# rn .time_1 A B
# 1: 1 1 1 10
# 2: 1 2 4 13
# 3: 1 3 7 16
# 4: 2 1 2 11
# 5: 2 2 5 14
# 6: 2 3 8 17
# 7: 3 1 3 12
# 8: 3 2 6 15
# 9: 3 3 9 18

为了公平/完整性,这里有一个使用“tidyr”+“dplyr”的方法。

library(tidyr)
library(dplyr)
df %>%
gather(var, value, A_1:B_3) %>%
separate(var, c("var", "time")) %>%
group_by(var, time) %>%
mutate(grp = sequence(n())) %>%
ungroup() %>%
spread(var, value)
# Source: local data frame [9 x 4]
#
# time grp A B
# 1 1 1 1 10
# 2 1 2 2 11
# 3 1 3 3 12
# 4 2 1 4 13
# 5 2 2 5 14
# 6 2 3 6 15
# 7 3 1 7 16
# 8 3 2 8 17
# 9 3 3 9 18

关于r - 在R中将数据帧从 "wide"格式转换为 "long"格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19361455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com