Reputation: 75
I have the following dataframe available for analysis.
Sname sid st.sn.s1 st.sn.s2 st.sn.s3 st.sn.s1 st.sn.s2 st.sn.s3
a 12 22 23 24 31 32 33
I want to convert it into something similar to the below one.
Sname sid st.sn.s1 st.sn.s2 st.sn.s3
a 12 22 23 24
a 12 31 32 33
Can anyone direct me to relevant resources or help on this?
Upvotes: 0
Views: 55
Reputation: 72813
Generalized base R solution, that accounts for multiple rows with different "Sname"
s.
res <- do.call(rbind, lapply(1:nrow(dat), function(x) {
x <- dat[x, ];cbind(x[1:2], rbind(x[3:5], x[6:8]), row.names=NULL)
}))
res
# Sname sid st.sn.s1 st.sn.s2 st.sn.s3
# 1 a 12 22 23 24
# 2 a 12 31 32 33
# 3 b 12 22 23 24
# 4 b 12 31 32 33
# 5 c 12 22 23 24
# 6 c 12 31 32 33
Data:
dat <- structure(list(Sname = c("a", "b", "c"), sid = c(12L, 12L, 12L
), st.sn.s1 = c(22L, 22L, 22L), st.sn.s2 = c(23L, 23L, 23L),
st.sn.s3 = c(24L, 24L, 24L), st.sn.s1 = c(31L, 31L, 31L),
st.sn.s2 = c(32L, 32L, 32L), st.sn.s3 = c(33L, 33L, 33L)), row.names = c(NA,
-3L), class = "data.frame")
Upvotes: 0
Reputation: 6489
You could the base R function rbind
:
df <- structure(list(Sname = "a", sid = 12L, st.sn.s1 = 22L, st.sn.s2 = 23L,
st.sn.s3 = 24L, st.sn.s1 = 31L, st.sn.s2 = 32L, st.sn.s3 = 33L), row.names = c(NA,
-1L), class = "data.frame")
rbind(df[, 1:5], df[, c(1:2, 6:8)])
# Sname sid st.sn.s1 st.sn.s2 st.sn.s3
# 1 a 12 22 23 24
# 2 a 12 31 32 33
Upvotes: 2
Reputation: 16178
Using pivot_longer
and pivot_wider
functions (https://tidyr.tidyverse.org/reference/pivot_longer.html), you can do:
library(tidyr)
library(dplyr)
df %>% pivot_longer(-c(Sname,sid), names_to = "var",values_to = "val") %>%
pivot_wider(names_from = var, values_from = val) %>%
dplyr::select(-.copy)
# A tibble: 2 x 5
Sname sid st.sn.s1 st.sn.s2 st.sn.s3
<chr> <int> <int> <int> <int>
1 a 12 22 23 24
2 a 12 31 32 33
Reproducible example
structure(list(Sname = "a", sid = 12L, st.sn.s1 = 22L, st.sn.s2 = 23L,
st.sn.s3 = 24L, st.sn.s1 = 31L, st.sn.s2 = 32L, st.sn.s3 = 33L), row.names = c(NA,
-1L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x5635c38695c0>)
Upvotes: 0