我有這樣的資料
library(tidyverse)
df = tribble(
~id, ~a1, ~a2, ~a3, ~b1, ~b2, ~b3, ~c1, ~c2, ~c3,
1, 1, 4, 7, 11, 14, 17, 21, 24, 27,
2, 2, 5, 8, 12, 15, 18, 22, 25, 28,
3, 3, 6, 8, 13, 16, 19, 23, 26, 29,
)
我想將其轉換為長格式,其中變數名稱包含名稱 (a, b, c) 和數字 (1, 2, 3) 兩部分,它們應該成為下表的長版本中的新變數,如下所示。
id name nr data
1 1 a 1 1
2 2 a 1 2
3 3 a 1 3
4 1 a 2 4
5 2 a 2 5
6 3 a 2 6
7 1 a 3 7
8 2 a 3 8
9 3 a 3 8
10 1 b 1 11
11 2 b 1 12
12 3 b 1 13
13 1 b 2 14
14 2 b 2 15
15 3 b 2 16
16 1 b 3 17
17 2 b 3 18
18 3 b 3 19
19 1 C 1 21
20 2 C 1 22
21 3 C 1 23
22 1 C 2 24
23 2 C 2 25
24 3 C 2 26
25 1 C 3 27
26 2 C 3 28
27 3 C 3 29
是否可以簡單地使用dplyr包中的函式來完成?我試過pivot_longer效果令人失望。
歡迎任何提示。
uj5u.com熱心網友回復:
我知道之前有人問過這個問題,但我找不到一個好的重復目標。同時,如果您指定正則運算式來區分列名的name部分和nr部分,則可以在一個函式呼叫中完成:
df %>%
pivot_longer(-id, names_to = c("name", "nr"),
values_to = "data",
names_pattern = "(^[a-z])(\\d$)")
#> # A tibble: 27 × 4
#> id name nr data
#> <dbl> <chr> <chr> <dbl>
#> 1 1 a 1 1
#> 2 1 a 2 4
#> 3 1 a 3 7
#> 4 1 b 1 11
#> 5 1 b 2 14
#> 6 1 b 3 17
#> 7 1 c 1 21
#> 8 1 c 2 24
#> 9 1 c 3 27
#> 10 2 a 1 2
#> # … with 17 more rows
如果您在實踐中有不同的列名,則根據需要調整正則運算式,但這會將它們分開,以便第一部分來自字串開頭的單個小寫字母,第二部分來自字串末尾的單個數字細繩。
uj5u.com熱心網友回復:
我們可以通過幾種方式做到這一點 - 即首先將“長”格式重塑為“長”格式,pivot_longer不包括“id”列,然后通過separate將“名稱”列指定sep為正則運算式環視 ie(因為只有一個小寫字母),在第一次出現字母 ( (?<=[a-z]))后拆分
library(dplyr)
library(tidyr)
df %>%
pivot_longer(cols = -id, names_to = 'name', values_to = 'data') %>%
separate(name, into = c("name", 'nr'), sep = "(?<=[a-z])")
-輸出
A tibble: 27 × 4
id name nr data
<dbl> <chr> <chr> <dbl>
1 1 a 1 1
2 1 a 2 4
3 1 a 3 7
4 1 b 1 11
5 1 b 2 14
6 1 b 3 17
7 1 c 1 21
8 1 c 2 24
9 1 c 3 27
10 2 a 1 2
# … with 17 more rows
或者另一種選擇是在列名中附加一個后綴,然后使用 pivot_longer
library(stringr)
df %>%
rename_with(~ str_c(., "_data"), -id) %>%
pivot_longer(cols = -id, names_to = c("name", "nr", ".value"),
names_pattern = "^(.)(.)_(.*)")
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/343050.html
上一篇:在R中的嵌套串列中計算
