在 R 中使用多个 header 行重塑数据
Reshape data with multiple header rows in R
Julie Joe
Measurement 1 Measurement 2 Measurement 1 Measurement 2
Part Number 1 33 32 33 31
Part Number 2 34 31 33 32
Part Number 3 33 31 30 31
我如何将这个凌乱Exceltable转换成整洁的格式以便在 R 中使用?我可以利用像 spread()
和 gather()
这样的 readr 函数,但这似乎需要更高的复杂度。这是我对 Excel 数据框的最佳重构,供您随意使用。请随意修改,以便更好地提出任何观点。
library(tidyverse)
messy <- data.frame(
" " = c(" ", "Part Number 1", "Part Number 2", "Part Number 3"),
Julie = c("Measurement 1", 33, 34, 33),
Julie = c("Measurement 2", 32, 31, 31),
Joe = c("Measurement 1", 33, 33, 30),
Joe = c("Measurement 2", 31, 32, 31))
我愿意尝试 readr 或 tidyr 的开发版本。新的pack()
、unpack()
等函数好像很有用。此外,似乎其他 SO attempts/solutions 并不是我要找的东西 1, , 3, .
棘手的部分是获取正确的列名,然后执行 gather
和 separate
,听起来您已经很熟悉了。通常我不喜欢按数字选择行,但在这种情况下,我认为如果您以这种方式可靠地从 Excel 读取数据是有意义的。
注意:如果一个人的名字中有.
,最后一步将失败。
library(tidyverse)
less_messy <- messy %>%
mutate_all(as.character) %>%
set_names(c("Part",
paste(names(.)[2:ncol(.)],
.[1, 2:ncol(.)],
sep = "-"))) %>%
`[`(2:nrow(.), ) %>%
gather("key", "value", contains("Measurement")) %>%
separate("key", c("person", "measurement"), sep = "-") %>%
mutate_at("person", ~ stringr::str_replace(.x, "\..*",""))
less_messy
#> Part person measurement value
#> 1 Part Number 1 Julie Measurement 1 33
#> 2 Part Number 2 Julie Measurement 1 34
#> 3 Part Number 3 Julie Measurement 1 33
#> 4 Part Number 1 Julie Measurement 2 32
#> 5 Part Number 2 Julie Measurement 2 31
#> 6 Part Number 3 Julie Measurement 2 31
#> 7 Part Number 1 Joe Measurement 1 33
#> 8 Part Number 2 Joe Measurement 1 33
#> 9 Part Number 3 Joe Measurement 1 30
#> 10 Part Number 1 Joe Measurement 2 31
#> 11 Part Number 2 Joe Measurement 2 32
#> 12 Part Number 3 Joe Measurement 2 31
数据
略有更改,因为我注意到您显示的内容与您的测量数字代码之间存在差异:
messy <- data.frame(
" " = c(" ", "Part Number 1", "Part Number 2", "Part Number 3"),
Julie = c("Measurement 1", 33, 34, 33),
Julie = c("Measurement 2", 32, 31, 31),
Joe = c("Measurement 1", 33, 33, 30),
Joe = c("Measurement 2", 31, 32, 31))
Julie Joe
Measurement 1 Measurement 2 Measurement 1 Measurement 2
Part Number 1 33 32 33 31
Part Number 2 34 31 33 32
Part Number 3 33 31 30 31
我如何将这个凌乱Exceltable转换成整洁的格式以便在 R 中使用?我可以利用像 spread()
和 gather()
这样的 readr 函数,但这似乎需要更高的复杂度。这是我对 Excel 数据框的最佳重构,供您随意使用。请随意修改,以便更好地提出任何观点。
library(tidyverse)
messy <- data.frame(
" " = c(" ", "Part Number 1", "Part Number 2", "Part Number 3"),
Julie = c("Measurement 1", 33, 34, 33),
Julie = c("Measurement 2", 32, 31, 31),
Joe = c("Measurement 1", 33, 33, 30),
Joe = c("Measurement 2", 31, 32, 31))
我愿意尝试 readr 或 tidyr 的开发版本。新的pack()
、unpack()
等函数好像很有用。此外,似乎其他 SO attempts/solutions 并不是我要找的东西 1,
棘手的部分是获取正确的列名,然后执行 gather
和 separate
,听起来您已经很熟悉了。通常我不喜欢按数字选择行,但在这种情况下,我认为如果您以这种方式可靠地从 Excel 读取数据是有意义的。
注意:如果一个人的名字中有.
,最后一步将失败。
library(tidyverse)
less_messy <- messy %>%
mutate_all(as.character) %>%
set_names(c("Part",
paste(names(.)[2:ncol(.)],
.[1, 2:ncol(.)],
sep = "-"))) %>%
`[`(2:nrow(.), ) %>%
gather("key", "value", contains("Measurement")) %>%
separate("key", c("person", "measurement"), sep = "-") %>%
mutate_at("person", ~ stringr::str_replace(.x, "\..*",""))
less_messy
#> Part person measurement value
#> 1 Part Number 1 Julie Measurement 1 33
#> 2 Part Number 2 Julie Measurement 1 34
#> 3 Part Number 3 Julie Measurement 1 33
#> 4 Part Number 1 Julie Measurement 2 32
#> 5 Part Number 2 Julie Measurement 2 31
#> 6 Part Number 3 Julie Measurement 2 31
#> 7 Part Number 1 Joe Measurement 1 33
#> 8 Part Number 2 Joe Measurement 1 33
#> 9 Part Number 3 Joe Measurement 1 30
#> 10 Part Number 1 Joe Measurement 2 31
#> 11 Part Number 2 Joe Measurement 2 32
#> 12 Part Number 3 Joe Measurement 2 31
数据
略有更改,因为我注意到您显示的内容与您的测量数字代码之间存在差异:
messy <- data.frame(
" " = c(" ", "Part Number 1", "Part Number 2", "Part Number 3"),
Julie = c("Measurement 1", 33, 34, 33),
Julie = c("Measurement 2", 32, 31, 31),
Joe = c("Measurement 1", 33, 33, 30),
Joe = c("Measurement 2", 31, 32, 31))