R通过identifer [duplicate]合并下来的列

问题描述 投票:0回答:4

我有一个很长的数据集,其中包含许多学期的学生成绩和课程。每个学生都有很多NA和许多行。我希望每个学生都有一排长长的行来填写这些NA,但要保留相同的列名。

这里是一个示例:

library(tidyverse)
sample <- tibble(student = c("Corey", "Corey", "Sibley", "Sibley"),
                 fall_course_1 = c("Math", NA, "Science", NA),
                 fall_course_2 = c(NA, "English", NA, NA),
                 fall_grade_1 = c(90, NA, 98, NA),
                 fall_grade_2 = c(NA, 60, NA, NA))

这是我想要的样子:

library(tidyverse)
answer <- tibble(student = c("Corey", "Sibley"),
                 fall_course_1 = c("Math", "Science"),
                 fall_course_2 = c("English", NA),
                 fall_grade_1 = c(90, 98),
                 fall_grade_2 = c(60, NA))

[有些学期,有些学生上许多课,有些只是一堂。我已经尝试过使用Coalesce(),但无法弄清楚。任何帮助,将不胜感激!

r reshape tidyr data-cleaning coalesce
4个回答
2
投票

您可以获得每个student在每一列中的第一个非NA值。

library(dplyr)
sample %> group_by(student) %>% summarise_all(~na.omit(.)[1])

# A tibble: 2 x 5
#  student fall_course_1 fall_course_2 fall_grade_1 fall_grade_2
#  <chr>   <chr>         <chr>                <dbl>        <dbl>
#1 Corey   Math          English                 90           60
#2 Sibley  Science       NA                      98           NA

如果组中存在所有NA值,则此方法返回NA


2
投票

使用自定义的colaesce函数和dplyr:

coalesce_all_columns <- function(df) {
  return(coalesce(!!! as.list(df)))
}

library(dplyr)

sample %>%
  group_by(student) %>%
  summarise_all(coalesce_all_columns)

# A tibble: 2 x 5
  student fall_course_1 fall_course_2 fall_grade_1 fall_grade_2
  <chr>   <chr>         <chr>                <dbl>        <dbl>
1 Corey   Math          English                 90           60
2 Sibley  Science       NA                      98           NA

2
投票

这应该执行,将数据旋转较长的长度,删除na,然后将其旋转回到较宽的位置。

您需要暂时将数值转换为字符,以便它们可以与课程标签放在同一列中,然后type_convert()是重新放回它们的一种惰性方法。

library(dplyr)
library(tidyr)
library(readr)

reshaped <- sample %>%
  mutate_if(is.numeric, as.character) %>%
  pivot_longer(-student) %>% 
  drop_na() %>% 
  pivot_wider(student, names_from = name, values_from = value) %>% 
  type_convert()

0
投票

您还可以如下使用data.table包:

library(data.table)
setDT(sample)[, lapply(.SD, na.omit), student]

sample
# 1:   Corey          Math       English           90           60
# 2:  Sibley       Science          <NA>           98           NA
© www.soinside.com 2019 - 2024. All rights reserved.