Мы можем использовать pivot_longer
из tidyr
, чтобы изменить форму столбцов с «широкого» на «длинный» после изменения имен столбцов, у которых нет нумерации c, заканчивающейся rename_at
library(dplyr)
library(tidyr)
library(stringr)
df1 %>%
rename_at(-1, ~ str_replace(., '([A-Z])$', '\\1_0')) %>%
pivot_longer(cols = -Id, names_to = c( ".value", "Status"),
names_sep = "_(?=[0-9])", values_drop_na = TRUE) %>%
mutate(Status = factor(Status, levels = 0:1, labels = c("Pre", "Post"))) %>%
arrange(Status)
# Id Status Col1_ABC Col2_BCD Col3_CBD
#1 1 Pre Yes No No
#2 2 Pre No No No
#3 3 Pre Yes Yes Yes
#4 4 Pre Yes No Yes
#5 5 Pre No No No
#6 1 Post Yes Yes No
#7 2 Post Yes No Yes
#8 3 Post No Yes No
Или другой вариант melt
из data.table
, где мы указываем patterns
в measure
для преобразования данных из «широкого» в «длинный» формат
library(data.table)
melt(setDT(df1), measure = patterns("Col1_ABC", "Col2_BCD", "Col3_CBD"),
na.rm = TRUE, variable.name = 'Status',
value.name = c("Col1_ABC", "Col2_BCD", "Col3_CBD"))[,
Status := c("Pre", "Post")[Status]][]
# Id Status Col1_ABC Col2_BCD Col3_CBD
#1: 1 Pre Yes No No
#2: 2 Pre No No No
#3: 3 Pre Yes Yes Yes
#4: 4 Pre Yes No Yes
#5: 5 Pre No No No
#6: 1 Post Yes Yes No
#7: 2 Post Yes No Yes
#8: 3 Post No Yes No
данные
df1 <- structure(list(Id = 1:5, Col1_ABC = c("Yes", "No", "Yes", "Yes",
"No"), Col2_BCD = c("No", "No", "Yes", "No", "No"), Col3_CBD = c("No",
"No", "Yes", "Yes", "No"), Col1_ABC_1 = c("Yes", "Yes", "No",
NA, NA), Col2_BCD_1 = c("Yes", "No", "Yes", NA, NA), Col3_CBD_1 = c("No",
"Yes", "No", NA, NA)), class = "data.frame", row.names = c(NA,
-5L))