Following up on this answer, I was wondering if there is a way to turn my wide-format data.frames (time1,time2,time1and2) into a single long-format data.frame to achieve my Desired_output below?
time1 =read.table(text="
class id order ac bc
1 1 s-c 1 2
",h=TRUE)
time2 =read.table(text="
class id order ac bc
1 1 s-c 3 4
",h=TRUE)
time1and2 =read.table(text="
class id order ex1S ex2S ex1C ex2C k1 k2 t1 t2
1 1 s-c 8 5 6 1 400 600 30 50
",h=TRUE)
# ave_ex = average of `ex`
Desired_output="
class id order time DV score k t ave_ex
1 1 s-c 1 ac 1 400 30 (8 5)/2 =6.5
1 1 s-c 1 bc 2 400 30 (8 5)/2 =6.5
1 1 s-c 2 ac 3 600 50 (6 1)/2 =3.5
1 1 s-c 2 bc 4 600 50 (6 1)/2 =3.5
"
CodePudding user response:
First, make them long format:
time1 <- pivot_longer(time1, c(ac, bc), names_to = "DV", values_to = "score") %>% mutate(time = 1)
time2 <- pivot_longer(time2, c(ac, bc), names_to = "DV", values_to = "score") %>% mutate(time = 2)
time1and2 <- pivot_longer(time1and2, c(k1:t2), names_to = c(".value", "time"), names_sep = "(\\d)") %>%
mutate(time = 1:2)
Then, unite:
bind_rows(time1, time2) %>% left_join(time1and2) %>%
mutate(ave = case_when(
time == 1 ~ mean(c(ex1S, ex2S)),
time == 2 ~ mean(c(ex1C, ex2C))
)) %>%
select(-c(ex1S:ex2C))
#Joining, by = c("class", "id", "order", "time")
## A tibble: 4 × 9
# class id order DV score time k t ave
# <int> <int> <chr> <chr> <int> <dbl> <int> <int> <dbl>
#1 1 1 s-c ac 1 1 400 30 6.5
#2 1 1 s-c bc 2 1 400 30 6.5
#3 1 1 s-c ac 3 2 600 50 3.5
#4 1 1 s-c bc 4 2 600 50 3.5
CodePudding user response:
In time1and2 (see the df2 part), you need to rename ex1S, ex2S, ex1C, ex2C to ex11, ex21, ex12, ex22 at first (here I use chartr() to achieve it), so that you can stack the pairs of
(ex11, ex12)toex1(ex21, ex22)toex2(k1, k2)tok(t1, t2)tot
at the same time.
library(tidyverse)
df1 <- list(time1, time2) %>%
map_dfr(~ pivot_longer(.x, ac:bc, names_to = "DV", values_to = "score"), .id = "time")
df2 <- time1and2 %>%
rename_with(~ chartr("SC", "12", .x), starts_with("ex")) %>%
pivot_longer(
ex11:t2,
names_to = c(".value", "time"),
names_pattern = "(. )(.)"
)
left_join(df1, df2) %>%
mutate(ave_ex = (ex1 ex2) / 2)
# # A tibble: 4 × 11
# time class id order DV score ex1 ex2 k t ave_ex
# <chr> <int> <int> <chr> <chr> <int> <int> <int> <int> <int> <dbl>
# 1 1 1 1 s-c ac 1 8 5 400 30 6.5
# 2 1 1 1 s-c bc 2 8 5 400 30 6.5
# 3 2 1 1 s-c ac 3 6 1 600 50 3.5
# 4 2 1 1 s-c bc 4 6 1 600 50 3.5
