I am trying to gather two sets of columns. Each set needs to end up in a new column, but the rows data is linked, so sequential uses of tidyr::gather()
won't guarantee retention of cross-column organization. It looks like tidyr::pivot_longer()
can accomplish this, but I am stumped. A similar post is here, but the answer involves using grep to rename columns, which I can't unravel and also shouldn't be necessary here.
library(tidyverse)
df <- data.frame(
Position=1:5,
A_Width=3:7,
B_Width=4:8,
A_Error=seq(0, 2.0, 0.5),
B_Error=seq(0.3, 1.5, 0.3)
)
df <- df %>%
tidyr::pivot_longer(
cols=c(A_Width, B_Width, A_Error, B_Error),
names_to= ? ,
names_pattern= ? ,
)
##Desired Data Frame
df_long <- data.frame(
Position=rep(1:5,2),
Group=c(rep("A",5), rep("B",5)),
Width=c(3:7,4:8),
Error=c(seq(0, 2.0, 0.5), seq(0.3, 1.5, 0.3))
)
We can use .value
with names_to
to use the second part of the column names to specify the new columns those values should go to.
df |>
pivot_longer(-Position, names_sep = "_", names_to = c("Group", ".value"))
Result (in order as encountered, could sort)
# A tibble: 10 × 4
Position Group Width Error
<int> <chr> <int> <dbl>
1 1 A 3 0
2 1 B 4 0.3
3 2 A 4 0.5
4 2 B 5 0.6
5 3 A 5 1
6 3 B 6 0.9
7 4 A 6 1.5
8 4 B 7 1.2
9 5 A 7 2
10 5 B 8 1.5