从1.0.0版起,tidyr软件包的功能pivot_longer()
就可以使用多个值/度量列从宽格式reshape 为长格式.
这比之前的tidyr策略gather()
比spread()
(见@AndrewMacDonald的答案)要好,因为属性不再被删除(在下面的示例中,日期仍然是日期,数字仍然是数字).
library("tidyr")
library("magrittr")
a <- structure(list(ID = 1L,
DateRange1Start = structure(7305, class = "Date"),
DateRange1End = structure(7307, class = "Date"),
Value1 = 4.4,
DateRange2Start = structure(7793, class = "Date"),
DateRange2End = structure(7856, class = "Date"),
Value2 = 6.2,
DateRange3Start = structure(9255, class = "Date"),
DateRange3End = structure(9653, class = "Date"),
Value3 = 3.3),
row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame"))
pivot_longer()
(对应:pivot_wider()
)与gather()
类似.
如果所有列名都遵循特定的模式,如Start_1
、End_1
、Start_2
等,这是最简单的.
(names(a) <- sub("(\\d)(\\w*)", "\\2_\\1", names(a)))
#> [1] "ID" "DateRangeStart_1" "DateRangeEnd_1"
#> [4] "Value_1" "DateRangeStart_2" "DateRangeEnd_2"
#> [7] "Value_2" "DateRangeStart_3" "DateRangeEnd_3"
#> [10] "Value_3"
pivot_longer(a,
cols = -ID,
names_to = c(".value", "group"),
# names_prefix = "DateRange",
names_sep = "_")
#> # A tibble: 3 x 5
#> ID group DateRangeEnd DateRangeStart Value
#> <int> <chr> <date> <date> <dbl>
#> 1 1 1 1990-01-03 1990-01-01 4.4
#> 2 1 2 1991-07-06 1991-05-04 6.2
#> 3 1 3 1996-06-06 1995-05-05 3.3
或者,可以使用提供更精细控制的pivot spec进行reshape (参见下面的链接):
spec <- a %>%
build_longer_spec(cols = -ID) %>%
dplyr::transmute(.name = .name,
group = readr::parse_number(name),
.value = stringr::str_extract(name, "Start|End|Value"))
pivot_longer(a, spec = spec)
由reprex package(v0.2.1)于2019-03-26创建
另见:https://tidyr.tidyverse.org/articles/pivot.html