我經常發現自己在一個情況下,我有一個包含寬列的多組,像這樣的表:整理表列寬多組,使用tidyverse
replicate groupA VA1 VA2 groupB VB1 VB2
1 1 a 0.3429166 -2.30336406 f 0.05363582 1.6454078
2 2 b -1.3183732 -0.13516849 g -0.42586417 0.1541541
3 3 c -0.7908358 -0.10746447 h 1.05134242 1.4297350
4 4 d -0.9963677 -1.82557058 i -1.14532536 1.0815733
5 5 e -1.3634609 0.04385812 j -0.65643595 -0.1452877
而且我想轉列成一個長表,像這樣:
replicate group key value
1 1 a V1 0.34291665
2 2 b V1 -1.31837322
3 3 c V1 -0.79083580
4 4 d V1 -0.99636772
5 5 e V1 -1.36346088
6 1 a V2 -2.30336406
7 2 b V2 -0.13516849
8 3 c V2 -0.10746447
9 4 d V2 -1.82557058
10 5 e V2 0.04385812
11 1 f V1 0.05363582
12 2 g V1 -0.42586417
13 3 h V1 1.05134242
14 4 i V1 -1.14532536
15 5 j V1 -0.65643595
16 1 f V2 1.64540784
17 2 g V2 0.15415408
18 3 h V2 1.42973499
19 4 i V2 1.08157329
20 5 j V2 -0.14528774
我可以通過分別選擇所述兩個組的列,整理,然後rbinding一起(下面的代碼)執行此操作。但是,這種方法看起來並不優雅,而且如果有兩組以上的列,則會變得很麻煩。我想知道是否有更優雅的方法,使用單個數據轉換管道鏈。
這裏最根本的問題是:我們如何自動化將表分成多組,整理這些表,然後再合併到一起的過程。
我當前的代碼:
library(dplyr)
library(tidyr)
# generate example code
df_wide <- data.frame(replicate = 1:5,
groupA = letters[1:5],
VA1 = rnorm(5),
VA2 = rnorm(5),
groupB = letters[6:10],
VB1 = rnorm(5),
VB2 = rnorm(5))
# tidy columns with A in the name
dfA <- select(df_wide, replicate, groupA, VA1, VA2) %>%
gather(key, value, VA1, VA2) %>%
mutate(key = case_when(key == "VA1" ~ "V1",
key == "VA2" ~ "V2")) %>%
select(replicate, group = groupA, key, value)
# tidy columns with B in the name
dfB <- select(df_wide, replicate, groupB, VB1, VB2) %>%
gather(key, value, VB1, VB2) %>%
mutate(key = case_when(key == "VB1" ~ "V1",
key == "VB2" ~ "V2")) %>%
select(replicate, group = groupB, key, value)
# combine
df_long <- rbind(dfA, dfB)
注:類似的問題已經被問here和here,但我想接受的答案顯示,這兒是個微妙的不同問題。
謝謝!我喜歡你的解決方案1,因爲它不需要硬編碼的列索引,並且適應許多不同的場景應該是相當直接的。 –
已將ifelse更改爲用於泛化爲> 2組的開關。 –
已添加新的(2)和(2a)並將舊的(2)移至(3)。 –