R重塑却交织?
R reshape but interweaved?
我需要将宽格式数据帧重塑为长格式。
我熟悉 melt() 函数并多次使用它。
df <- data.frame( Weekday = c( "Mon", "Tues", "Wed", "Thurs", "Fri" ),
Q1 = c( 9.9 , 4.9 , 8.8 , 12.2 , 12.2 ),
Q2 = c( 5.4 , 9.7 , 11.1 , 10.2 , 8.1 ),
Q3 = c( 8.8 , 7.9 , 10.2 , 9.2 , 7.9 ),
Q4 = c( 6.9 , 5 , 9.3 , 9.7 , 5.6 ) )
df_melt <- melt(df, id.vars=c("Weekday"),
variable.name="Quarter",
value.name="Delay")
上述函数将给出以下输出:
Weekday Quarter Delay
Mon Q1 9.9
Tues Q1 4.9
Wed Q1 8.8
Thurs Q1 12.2
Fri Q1 12.2
Mon Q2 5.4
Tues Q2 9.7
Wed Q2 11.1
... ... ...
但是,我希望我的长格式看起来像这样:
Weekday Quarter Delay
Mon Q1 9.9
Mon Q2 5.4
Mon Q3 8.8
Mon Q4 6.9
Tues Q1 4.9
Tues Q2 9.7
... ... ...
R 中是否有允许我执行此操作的函数?
您可以 match
和 order
输出带有您想要的顺序的向量。
order_vec <- c('Mon', 'Tues', 'Wed', 'Thurs', 'Fri')
df_melt[order(match(df_melt$Weekday, order_vec)), ]
# Weekday Quarter Delay
#1 Mon Q1 9.9
#6 Mon Q2 5.4
#11 Mon Q3 8.8
#16 Mon Q4 6.9
#2 Tues Q1 4.9
#7 Tues Q2 9.7
#...
#...
如果您使用 tidyr::pivot_longer
而不是 melt
,它将直接为您提供您想要的顺序。
tidyr::pivot_longer(df, cols = -Weekday)
# Weekday name value
# <chr> <chr> <dbl>
# 1 Mon Q1 9.9
# 2 Mon Q2 5.4
# 3 Mon Q3 8.8
# 4 Mon Q4 6.9
# 5 Tues Q1 4.9
# 6 Tues Q2 9.7
# 7 Tues Q3 7.9
#...
#...
我们可以 melt
数据集和 factor
上的 order
转换 'Weekday' 并将 levels
指定为 unique
值
library(data.table)
melt(setDT(df), id.var = 'Weekday', variable.name = 'Quarter',
value.name = 'Delay')[order(factor(Weekday, levels = unique(Weekday)))]
-输出
Weekday Quarter Delay
1: Mon Q1 9.9
2: Mon Q2 5.4
3: Mon Q3 8.8
4: Mon Q4 6.9
5: Tues Q1 4.9
6: Tues Q2 9.7
7: Tues Q3 7.9
8: Tues Q4 5.0
9: Wed Q1 8.8
10: Wed Q2 11.1
11: Wed Q3 10.2
12: Wed Q4 9.3
13: Thurs Q1 12.2
14: Thurs Q2 10.2
15: Thurs Q3 9.2
16: Thurs Q4 9.7
17: Fri Q1 12.2
18: Fri Q2 8.1
19: Fri Q3 7.9
20: Fri Q4 5.6
或者这可以用 base R
完成,方法是 rep
连接 'Weekday' 和列名,同时 t
排列除第一个
data.frame(Weekday = rep(df$Weekday, each = 4),
Quarter = rep(names(df)[-1], 5), Delay = c(t(df[-1])))
Weekday Quarter Delay
1 Mon Q1 9.9
2 Mon Q2 5.4
3 Mon Q3 8.8
4 Mon Q4 6.9
5 Tues Q1 4.9
6 Tues Q2 9.7
7 Tues Q3 7.9
8 Tues Q4 5.0
9 Wed Q1 8.8
10 Wed Q2 11.1
11 Wed Q3 10.2
12 Wed Q4 9.3
13 Thurs Q1 12.2
14 Thurs Q2 10.2
15 Thurs Q3 9.2
16 Thurs Q4 9.7
17 Fri Q1 12.2
18 Fri Q2 8.1
19 Fri Q3 7.9
20 Fri Q4 5.6
为了完整起见,forcats 包中的 as_factor()
函数根据字符向量 按照它们出现的顺序 创建级别。这可用于按要求订购 df_melt()
:
df_melt[order(forcats::as_factor(df_melt$Weekday)), ]
Weekday Quarter Delay
1 Mon Q1 9.9
6 Mon Q2 5.4
11 Mon Q3 8.8
16 Mon Q4 6.9
2 Tues Q1 4.9
7 Tues Q2 9.7
12 Tues Q3 7.9
17 Tues Q4 5.0
3 Wed Q1 8.8
8 Wed Q2 11.1
13 Wed Q3 10.2
18 Wed Q4 9.3
4 Thurs Q1 12.2
9 Thurs Q2 10.2
14 Thurs Q3 9.2
19 Thurs Q4 9.7
5 Fri Q1 12.2
10 Fri Q2 8.1
15 Fri Q3 7.9
20 Fri Q4 5.6
这也可以用来简化:
library(data.table)
melt(setDT(df), id.var = 'Weekday', variable.name = 'Quarter',
value.name = 'Delay')[order(forcats::as_factor(Weekday))]
Weekday Quarter Delay
1: Mon Q1 9.9
2: Mon Q2 5.4
3: Mon Q3 8.8
4: Mon Q4 6.9
5: Tues Q1 4.9
6: Tues Q2 9.7
7: Tues Q3 7.9
8: Tues Q4 5.0
9: Wed Q1 8.8
10: Wed Q2 11.1
11: Wed Q3 10.2
12: Wed Q4 9.3
13: Thurs Q1 12.2
14: Thurs Q2 10.2
15: Thurs Q3 9.2
16: Thurs Q4 9.7
17: Fri Q1 12.2
18: Fri Q2 8.1
19: Fri Q3 7.9
20: Fri Q4 5.6
我需要将宽格式数据帧重塑为长格式。
我熟悉 melt() 函数并多次使用它。
df <- data.frame( Weekday = c( "Mon", "Tues", "Wed", "Thurs", "Fri" ),
Q1 = c( 9.9 , 4.9 , 8.8 , 12.2 , 12.2 ),
Q2 = c( 5.4 , 9.7 , 11.1 , 10.2 , 8.1 ),
Q3 = c( 8.8 , 7.9 , 10.2 , 9.2 , 7.9 ),
Q4 = c( 6.9 , 5 , 9.3 , 9.7 , 5.6 ) )
df_melt <- melt(df, id.vars=c("Weekday"),
variable.name="Quarter",
value.name="Delay")
上述函数将给出以下输出:
Weekday Quarter Delay
Mon Q1 9.9
Tues Q1 4.9
Wed Q1 8.8
Thurs Q1 12.2
Fri Q1 12.2
Mon Q2 5.4
Tues Q2 9.7
Wed Q2 11.1
... ... ...
但是,我希望我的长格式看起来像这样:
Weekday Quarter Delay
Mon Q1 9.9
Mon Q2 5.4
Mon Q3 8.8
Mon Q4 6.9
Tues Q1 4.9
Tues Q2 9.7
... ... ...
R 中是否有允许我执行此操作的函数?
您可以 match
和 order
输出带有您想要的顺序的向量。
order_vec <- c('Mon', 'Tues', 'Wed', 'Thurs', 'Fri')
df_melt[order(match(df_melt$Weekday, order_vec)), ]
# Weekday Quarter Delay
#1 Mon Q1 9.9
#6 Mon Q2 5.4
#11 Mon Q3 8.8
#16 Mon Q4 6.9
#2 Tues Q1 4.9
#7 Tues Q2 9.7
#...
#...
如果您使用 tidyr::pivot_longer
而不是 melt
,它将直接为您提供您想要的顺序。
tidyr::pivot_longer(df, cols = -Weekday)
# Weekday name value
# <chr> <chr> <dbl>
# 1 Mon Q1 9.9
# 2 Mon Q2 5.4
# 3 Mon Q3 8.8
# 4 Mon Q4 6.9
# 5 Tues Q1 4.9
# 6 Tues Q2 9.7
# 7 Tues Q3 7.9
#...
#...
我们可以 melt
数据集和 factor
上的 order
转换 'Weekday' 并将 levels
指定为 unique
值
library(data.table)
melt(setDT(df), id.var = 'Weekday', variable.name = 'Quarter',
value.name = 'Delay')[order(factor(Weekday, levels = unique(Weekday)))]
-输出
Weekday Quarter Delay
1: Mon Q1 9.9
2: Mon Q2 5.4
3: Mon Q3 8.8
4: Mon Q4 6.9
5: Tues Q1 4.9
6: Tues Q2 9.7
7: Tues Q3 7.9
8: Tues Q4 5.0
9: Wed Q1 8.8
10: Wed Q2 11.1
11: Wed Q3 10.2
12: Wed Q4 9.3
13: Thurs Q1 12.2
14: Thurs Q2 10.2
15: Thurs Q3 9.2
16: Thurs Q4 9.7
17: Fri Q1 12.2
18: Fri Q2 8.1
19: Fri Q3 7.9
20: Fri Q4 5.6
或者这可以用 base R
完成,方法是 rep
连接 'Weekday' 和列名,同时 t
排列除第一个
data.frame(Weekday = rep(df$Weekday, each = 4),
Quarter = rep(names(df)[-1], 5), Delay = c(t(df[-1])))
Weekday Quarter Delay
1 Mon Q1 9.9
2 Mon Q2 5.4
3 Mon Q3 8.8
4 Mon Q4 6.9
5 Tues Q1 4.9
6 Tues Q2 9.7
7 Tues Q3 7.9
8 Tues Q4 5.0
9 Wed Q1 8.8
10 Wed Q2 11.1
11 Wed Q3 10.2
12 Wed Q4 9.3
13 Thurs Q1 12.2
14 Thurs Q2 10.2
15 Thurs Q3 9.2
16 Thurs Q4 9.7
17 Fri Q1 12.2
18 Fri Q2 8.1
19 Fri Q3 7.9
20 Fri Q4 5.6
为了完整起见,forcats 包中的 as_factor()
函数根据字符向量 按照它们出现的顺序 创建级别。这可用于按要求订购 df_melt()
:
df_melt[order(forcats::as_factor(df_melt$Weekday)), ]
Weekday Quarter Delay 1 Mon Q1 9.9 6 Mon Q2 5.4 11 Mon Q3 8.8 16 Mon Q4 6.9 2 Tues Q1 4.9 7 Tues Q2 9.7 12 Tues Q3 7.9 17 Tues Q4 5.0 3 Wed Q1 8.8 8 Wed Q2 11.1 13 Wed Q3 10.2 18 Wed Q4 9.3 4 Thurs Q1 12.2 9 Thurs Q2 10.2 14 Thurs Q3 9.2 19 Thurs Q4 9.7 5 Fri Q1 12.2 10 Fri Q2 8.1 15 Fri Q3 7.9 20 Fri Q4 5.6
这也可以用来简化
library(data.table)
melt(setDT(df), id.var = 'Weekday', variable.name = 'Quarter',
value.name = 'Delay')[order(forcats::as_factor(Weekday))]
Weekday Quarter Delay 1: Mon Q1 9.9 2: Mon Q2 5.4 3: Mon Q3 8.8 4: Mon Q4 6.9 5: Tues Q1 4.9 6: Tues Q2 9.7 7: Tues Q3 7.9 8: Tues Q4 5.0 9: Wed Q1 8.8 10: Wed Q2 11.1 11: Wed Q3 10.2 12: Wed Q4 9.3 13: Thurs Q1 12.2 14: Thurs Q2 10.2 15: Thurs Q3 9.2 16: Thurs Q4 9.7 17: Fri Q1 12.2 18: Fri Q2 8.1 19: Fri Q3 7.9 20: Fri Q4 5.6