GATHER

    student_data <- data.frame(
        student_id = 1:50,
        name = paste0("Student", 1:50),
        midterm1 = sample(60:100, 50, replace = TRUE),
        midterm2 = sample(60:100, 50, replace = TRUE),
        final = sample(60:100, 50, replace = TRUE)
    )
    student_data_long <- gather(student_data, key="exam_type", value="score", -student_id, -name)
    kable(head(student_data_long),align="c")
student_id name exam_type score
1 Student1 midterm1 61
2 Student2 midterm1 85
3 Student3 midterm1 75
4 Student4 midterm1 86
5 Student5 midterm1 64
6 Student6 midterm1 64

SEPARATE

    student_data_b <- data.frame(
        student_id = 1:50,
        name_age = c("John_21", "Alice_20", "Bob_22", "Emily_23", "Michael_22"),
        exam_scores = c("midterm1_80,midterm2_85,final_75", "midterm1_75,midterm2_78,final_80", "midterm1_82,midterm2_80,final_85", "midterm1_88,midterm2_90,final_92", "midterm1_85,midterm2_86,final_88")
    )
    student_data_b <- separate(student_data_b, name_age, c("Name", "Age"), convert = TRUE)
    student_data_b <- separate_rows(student_data_b, exam_scores, sep="[,]") %>% separate(exam_scores, c("exam_type", "score"), sep="_", convert = TRUE)
    kable(head(student_data_b),align="c")
student_id Name Age exam_type score
1 John 21 midterm1 80
1 John 21 midterm2 85
1 John 21 final 75
2 Alice 20 midterm1 75
2 Alice 20 midterm2 78
2 Alice 20 final 80

COMPLETE

    student_data_c<- data.frame(
        id = 1:50,
        name = c("John", "Alice", "Bob", "Emily", "Michael"),
        age = c(25, 20, 30, 40, 22),
        score = c(90, 85, 75, NA, 95)
    )
    student_data_c <- complete(student_data_c, fill = list(score = 0))
    kable(head(student_data_c),align="c")
id name age score
1 John 25 90
2 Alice 20 85
3 Bob 30 75
4 Emily 40 0
5 Michael 22 95
6 John 25 90

SPREAD

    student_data_d <- data.frame(
        student_id = 1:50,
        name_age = c("John_21", "Alice_20", "Bob_22", "Emily_23", "Michael_22"),
        exam_scores = c("midterm1_80,midterm2_85,final_75", "midterm1_75,midterm2_78,final_80", "midterm1_82,midterm2_80,final_85", "midterm1_88,midterm2_90,final_92", "midterm1_85,midterm2_86,final_88")
    )
    student_data_d <- separate(student_data_d, name_age, c("Name", "Age"), convert = TRUE)
    student_data_d <- separate_rows(student_data_d, exam_scores, sep="[,]") %>% separate(exam_scores, c("exam_type", "score"), sep="_", convert = TRUE)
    student_data_wide <- spread(student_data_d,exam_type,score)
    kable(head(student_data_wide),,align="c")
student_id Name Age final midterm1 midterm2
1 John 21 75 80 85
2 Alice 20 80 75 78
3 Bob 22 85 82 80
4 Emily 23 92 88 90
5 Michael 22 88 85 86
6 John 21 75 80 85

UNITE

    student_data_e <- data.frame(
        student_id = 1:50,
        name_age = c("John_21", "Alice_20", "Bob_22", "Emily_23", "Michael_22"),
        exam_scores = c("midterm1_80,midterm2_85,final_75", "midterm1_75,midterm2_78,final_80", "midterm1_82,midterm2_80,final_85", "midterm1_88,midterm2_90,final_92", "midterm1_85,midterm2_86,final_88")
    )
    student_data_e <- separate(student_data_e, name_age, c("name", "age"), convert = TRUE)
    student_data_e <- separate_rows(student_data_e, exam_scores, sep = "[,]") %>% separate(exam_scores, c("exam_type", "score"), sep = "_", convert = TRUE)
    student_data_e <- unite(student_data_e, name_age, name, age, sep = "_", remove = TRUE, na.rm = FALSE)
    kable(head(student_data_e),align="c")
student_id name_age exam_type score
1 John_21 midterm1 80
1 John_21 midterm2 85
1 John_21 final 75
2 Alice_20 midterm1 75
2 Alice_20 midterm2 78
2 Alice_20 final 80