Как отфильтровать даты в разных строках? - PullRequest
1 голос
/ 29 марта 2020

Предположим, у меня есть фрейм данных

abc<- children_info
child_name  custody_start   custody_end
jon         01/01/2018      04/29/2018
jon         05/01/2018      05/25/2018
jon         05/29/2018      07/31/2018
paul        03/22/2018      07/15/2019
paul        06/09/2019      03/28/2020

Я хочу отфильтровать дату каждого первичного хранениядети и дату последнего хранения и изменить его в новом столбце. В пакете dplyr, какой лучший способ go об этом?

Ответы [ 3 ]

3 голосов
/ 29 марта 2020

Как насчет этого:

library(dplyr)
mydat %>%
  mutate_at(vars(custody_start, custody_end), ~ as.Date(., "%m/%d/%Y")) %>%
  group_by(child_name) %>%
  summarize(
    custody_start = min(custody_start),
    custody_end = max(custody_end)
  )
# # A tibble: 2 x 3
#   child_name custody_start custody_end
#   <chr>      <date>        <date>     
# 1 jon        2018-01-01    2018-07-31 
# 2 paul       2018-03-22    2020-03-28 

Данные:

mydat <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
child_name  custody_start   custody_end
jon         01/01/2018      04/29/2018
jon         05/01/2018      05/25/2018
jon         05/29/2018      07/31/2018
paul        03/22/2018      07/15/2019
paul        06/09/2019      03/28/2020")
2 голосов
/ 29 марта 2020

Используя data.table

library(data.table)
nm1 <- c('custody_start', 'custody_end')
setDT(df1)[, (nm1) := lapply(.SD, as.IDate, format = "%m/%d/%Y"),
       .SDcols = nm1][,  .(custody_start = min(custody_start),
             custody_end = max(custody_end)), .(child_name)]
#   child_name custody_start custody_end
#1:        jon    2018-01-01  2018-07-31
#2:       paul    2018-03-22  2020-03-28

Или используя tidyverse

library(dplyr)
library(lubridate)
df1 %>% 
    group_by(child_name) %>%
    summarise(custody_start = min(mdy(custody_start)),
              custody_end = max(mdy(custody_end)))
# A tibble: 2 x 3
#  child_name custody_start custody_end
#  <chr>      <date>        <date>     
#1 jon        2018-01-01    2018-07-31 
#2 paul       2018-03-22    2020-03-28 

Или в base R

by(df1, df1$child_name, FUN = function(x) 
   data.frame(child_name = x$child_name[1],
              custody_start = min(as.Date(x$custody_start, "%m/%d/%Y")), 
              custody_end = max(as.Date(x$custody_end, "%m/%d/%Y"))))

данные

df1 <- structure(list(child_name = c("jon", "jon", "jon", "paul", "paul"
), custody_start = c("01/01/2018", "05/01/2018", "05/29/2018", 
"03/22/2018", "06/09/2019"), custody_end = c("04/29/2018", "05/25/2018", 
"07/31/2018", "07/15/2019", "03/28/2020")), 
    class = "data.frame", row.names = c(NA, 
-5L))
1 голос
/ 29 марта 2020

Базовое решение R:

data.frame(do.call("rbind", lapply(split(mydat, mydat$child_name), function(x){
        data.frame(child_name = unique(x$child_name), 
                   custody_start = min(x$custody_start, na.rm = TRUE),
                   custody_end = max(x$custody_end, na.rm = TRUE))
      }
    )
  ),
row.names = NULL)

Тидиверс решение:

library(tidyverse)
mydat %>% 
  group_by(child_name) %>% 
  summarise(custody_start = min(custody_start, na.rm = TRUE), 
            custody_end = max(custody_end, na.rm = TRUE)) %>% 
  ungroup()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...