首页 > 解决方案 > 从长文件中获取第一个事件并转换为宽文件

问题描述

Ciao,我为每个学生设置了几行。ID 等于学生 ID,DAY_DISCIPLINE_A 等于学生因“A”被处分的学年日期,DAY_DISCIPLINE_B 等于学生因“B”被处分的学年日期

这是我的复制示例

HAVE <- data.frame(ID=c(1,1,1,2,2,2,3,3,3,4,4,4),
                   DAY_DISCIPLINE_A=c(12,15,NA,10,NA,NA,NA,NA,16,NA,NA,NA),
                   DAY_DISCIPLINE_B=c(NA,NA,NA,10,11,12,NA,14,NA,NA,NA,NA))

我的目标是创建新的数据框,其中每个学生都有 1 行,此处显示为示例

WANT <- data.frame(ID=c(1,2,3,4),
                   DAY=c(12,10,14,-99),
                   DISCIPLINE=c("A","B","B","none"))

在这个例子中,每个学生都有 1 行;DAY 等于学生接受的第一个学科的日期,无论是 A 还是 B(DAY 的最小值),DISCIPLINE 等于 DISCIPLINE 的类型。换句话说,现在;我的目标是创建一个新的数据文件,其中每个 ID 都有一行,我首先捕获学生的 DISCIPLINE 并报告该 DISCIPLINE 的类型和日期。如果没有DISCIPLINE 被报告,那么DAY 应该是-99 并且DISCIPLINE 应该是“none”。如果纪律 A 和 B 发生在同一天,那么我报告那一天并将所有关系的纪律设置为 B。

标签: rdplyrreshape

解决方案


利用“B”在“A”之后的事实,这是一种简单的方法,dplyr并且tidyr-

library(dplyr)
library(tidyr)

WANT <- gather(HAVE, key = "DISCIPLINE", value = "DAY", DAY_DISCIPLINE_A, DAY_DISCIPLINE_B) %>%
  arrange(ID, DAY, desc(DISCIPLINE)) %>%
  group_by(ID) %>%
  filter(row_number() == 1) %>%
  mutate(
    DISCIPLINE =  ifelse(is.na(DAY), "none", substring(DISCIPLINE, 16, 16)),
    DAY = ifelse(is.na(DAY), -99, DAY)
  )

# A tibble: 4 x 3
# Groups:   ID [4]
     ID DISCIPLINE   DAY
  <dbl> <chr>      <dbl>
1  1.00 A           12.0
2  2.00 B           10.0
3  3.00 B           14.0
4  4.00 none       -99.0

mutate 语句仅用于外观更改,如果没有必要可以避免。


推荐阅读