Как преобразовать фрейм данных с более чем 3 столбцами в R? - PullRequest
0 голосов
/ 27 апреля 2018

При импорте из базы данных Access у меня есть данные, которые выглядят примерно так:

p <- data.frame(SurvDate = as.Date(c('2018-11-1','2018-11-1','2018-11-1',
                                     '2018-11-3', '2018-11-3')), 
                Area = c('AF','BB','CT', 'DF', 'BB'), 
                pCount = c(6, 3, 0, 12, 32), 
                ObsTime = c('8:51','8:59','9:13', '9:24', '9:30'), 
                stringsAsFactors = FALSE)

Я хочу преобразовать мои данные со строками в виде SurvDate, а столбцы - в области (значения в виде pCount) и столбцы ObsTime рядом с каждой областью со значением ObsTime.

Пример:

n <- data.frame(SurvDate = as.Date(c('2018-11-1','2018-11-3')), 
                AF = c(6, NA), 
                TimeAF = c('8:51', NA), 
                BB = c(3, 32), 
                TimeBB = c('8:59', '9:30'), 
                CT = c(0, NA), 
                TimeCT = c(NA, '9:13'), 
                DF = c(NA,12), 
                TimeDF = c(NA, '9:24'))

Я пробовал вариации на эту тему, но не могу найти время для работы.

library(reshape2)
dcast(p, SurvDate+ObsTime ~ Area)

1 Ответ

0 голосов
/ 27 апреля 2018

Вот один из способов использования tidyverse инструментов. Обратите внимание, что выходные данные не совпадают с ожидаемыми, потому что кажется, что вы не поместили значения для CT в нужное место (значения распределены по двум датам). Подход заключается в unite значениях, поэтому мы имеем одну пару ключ-значение в spread, а затем снова разделяем столбцы с помощью mutate_at. Мы также могли бы использовать separate несколько раз, хотя это было бы громоздким при слишком большом количестве Area с.

SurvDate <- as.Date(c('2018-11-1','2018-11-1','2018-11-1', '2018-11-3', '2018-11-3'))
Area <- c('AF','BB','CT', 'DF', 'BB')
People <- c(6, 3, 0, 12, 32)
ObsTime <- (c('8:51','8:59','9:13', '9:24', '9:30'))
p <- data.frame(SurvDate, Area, People, ObsTime, stringsAsFactors = FALSE)

library(tidyverse)
p %>%
  unite(vals, People, ObsTime) %>%
  spread(Area, vals) %>%
  mutate_at(
    .vars = vars(-SurvDate),
    .funs = funs(
      Time = str_extract(., "(?<=_).*$"),
      Area = str_extract(., "^.*(?=_)")
    )
  ) %>%
  filter(!is.na(SurvDate)) %>%
  select(SurvDate,  matches("_")) %>%
  select(SurvDate, order(colnames(.)))
#>     SurvDate AF_Area AF_Time BB_Area BB_Time CT_Area CT_Time DF_Area
#> 1 2018-11-01       6    8:51       3    8:59       0    9:13    <NA>
#> 2 2018-11-03    <NA>    <NA>      32    9:30    <NA>    <NA>      12
#>   DF_Time
#> 1    <NA>
#> 2    9:24

Создано в 2018-04-30 пакетом Представ. (v0.2.0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...