I'm trying to split columns in a dataframe and place them next to each other based on a single factor column. I would like to turn this:
TOD Value
1 Day 135
2 Day 513
3 Day 567
4 Day 848
5 Day 578
6 Night 145
7 Night 267
8 Night 589
9 Night 258
10 Night 278
and turn it into this:
TOD Value TOD_2 Value_2
1 Day 135 Night 145
2 Day 513 Night 267
3 Day 567 Night 589
4 Day 848 Night 258
5 Day 578 Night 278
How do I do this?
CodePudding user response:
Assuming your data frame is called df
, you could do:
do.call(cbind, split(df, df$TOD)) |>
setNames(c(names(df), paste0(names(df), "_2")))
#> TOD Value TOD_2 Value_2
#> 1 Day 135 Night 145
#> 2 Day 513 Night 267
#> 3 Day 567 Night 589
#> 4 Day 848 Night 258
#> 5 Day 578 Night 278
Data from question in reproducible format
df <- structure(list(TOD = c("Day", "Day", "Day", "Day", "Day", "Night",
"Night", "Night", "Night", "Night"), Value = c(135L, 513L, 567L,
848L, 578L, 145L, 267L, 589L, 258L, 278L)),
class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10"))
CodePudding user response:
A tidy solution using group_split
and bind_cols
:
library(dplyr)
df %>%
group_split(TOD) %>%
Map(function(x, y) {names(x) <- paste(names(x), y, sep = "_"); x}, ., 1:length(.)) %>%
bind_cols()
# # A tibble: 5 × 4
# TOD_1 Value_1 TOD_2 Value_2
# <chr> <int> <chr> <int>
# 1 Day 135 Night 145
# 2 Day 513 Night 267
# 3 Day 567 Night 589
# 4 Day 848 Night 258
# 5 Day 578 Night 278