Возьмите первое событие из длинного файла и преобразуйте в широкий файл - PullRequest
0 голосов
/ 08 октября 2018

Чао, у меня есть несколько строк для каждого студента.Идентификатор равен идентификатору студента, 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 ряд;ДЕНЬ соответствует дню ПЕРВОЙ дисциплины, которую получил студент, независимо от того, является ли это А или В (самое низкое значение ДНЯ), а ДИСЦИПЛИНА соответствует типу ДИСЦИПЛИНЫ.Теперь другими словами;Я стремлюсь создать новый файл данных, в котором у каждого идентификатора есть одна строка, и я сначала записываю учеников DISCIPLINE и сообщаю ТИП и ДЕНЬ этого DISCIPLINE.Если о DISCIPLINE не сообщается, тогда DAY должен быть -99, а DISCIPLINE - «none».Если ДИСЦИПЛИНА A и B происходят в один и тот же день, я сообщаю об этом ДНЕ и устанавливаю DISCIPLINE равным B для всех связей.

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Вот один из способов сделать это с tidyverse, сначала мы преобразуем в long, а затем суммируем по минимальному значению.Затем отфильтруйте туда, где value == min(value), затем, наконец, создайте DISCIPLINE, и это немного «хаккейно», потому что мы берем max символьного вектора, выбираем B, если он существует, в противном случае A

library(tidyverse)
library(reshape2)

melt(HAVE,id = "ID") %>% group_by(ID, variable) %>% 
  summarize(value= min(na.omit(value))) %>% 
  filter(value == min(value)) %>% 
  mutate(DISCIPLINE = substr(variable, 16,16)) %>% 
  filter(DISCIPLINE == max(DISCIPLINE)) %>%
  mutate(value = ifelse(value == Inf,-99,value)) %>%
  select(-variable)

# A tibble: 4 x 3
# Groups:   ID [4]
     ID value DISCIPLINE
  <dbl> <dbl> <chr>     
1     1    12 A         
2     2    10 B         
3     3    14 B         
4     4   -99 B  
0 голосов
/ 08 октября 2018

Принимая во внимание тот факт, что «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 необходим только для косметикиизменения и их можно избежать, если не нужно.

0 голосов
/ 08 октября 2018

С data.table ...

library(data.table)
# transform to long form, sort by DAY, drop duplicates
res = melt(setDT(HAVE), "ID", variable.name="DISCIPLINE", value.name="DAY")[order(DAY, -DISCIPLINE), .SD[1], keyby=ID]

# overwrite DISCIPLINE if DAY is blank    
res[is.na(DAY), DISCIPLINE := NA][]


   ID       DISCIPLINE DAY
1:  1 DAY_DISCIPLINE_A  12
2:  2 DAY_DISCIPLINE_B  10
3:  3 DAY_DISCIPLINE_B  14
4:  4             <NA>  NA

Для перевода в dplyr + tidyr, см. ?gather, ?arrange, ?distinct.

Для анализа в R,Вы должны использовать NA вместо пользовательских кодов пропущенных данных («none», -99).Если вам нужно это сделать, хотя (например, печать в Excel), последняя строка выше показывает, как это можно сделать.

Если вы хотите очистить столбец DISCIPLINE, чтобы отображались только A и B, есть...

patt = "^DAY_DISCIPLINE_(\\w+)$"
res[DISCIPLINE %like% patt, DISCIPLINE := sub(patt, "\\1", DISCIPLINE)][]

   ID DISCIPLINE DAY
1:  1          A  12
2:  2          B  10
3:  3          B  14
4:  4       <NA>  NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...