2016-08-06 2 views
1

Здравствуйте, я пытаюсь написать функцию, которая принимает в dataframe, и которая преобразует все типы POSIXct или POSIXlt в тип Date в R. Я создал часть функции, но я застрял на итерации по элементам в каждом индексе.Функция для преобразования класса POSIXct в Date

#Basic Data Frame 
patientID <- c(1, 2, 3, 4) 
AdmDate <- as.POSIXct(c('2010-10-11','2008-3-25','2016-4-23','2011-6-12')) 
diabetes <- c("Type1", "Type2", "Type1", "Type2") 
status <- c("Poor", "Improved", "Excellent", "Poor") 
patientdata <- data.frame(patientID, AdmDate, diabetes, status) 


convertallPOSIXct <- function(data){ 
if(getdata[[is.POSIXt()=='TRUE']]) 
    getdata[[]] <- class(as.Date()) 
} 

getdata <- function(x) { 
    chr_test <- x %>% 
    map_chr(~ paste(class(.), collapse = "/")) 
} 

Функция данных прибудут, кажется, работает, но я не знаю, как принять каждый элемент из GetData и превратить его в класс Date в R. Спасибо!

ответ

4

Вот один вариант с lapply:

df <- patientdata 

df[] <- lapply(df, function(x) { 
    if (inherits(x, "POSIXt")) as.Date(x) else x 
}) 

str(df) 
# 'data.frame': 4 obs. of 4 variables: 
# $ patientID: num 1 2 3 4 
# $ AdmDate : Date, format: "2010-10-11" "2008-03-25" ... 
# $ diabetes : chr "Type1" "Type2" "Type1" "Type2" 
# $ status : chr "Poor" "Improved" "Excellent" "Poor" 

[] необходимо сохранить data.frame структуру, иначе вы бы в конечном итоге с обычным списком. Использование inherits вместо class(object) == "some_class" является предпочтительным, поскольку, если объект имеет несколько классов - которые POSIXt объектов сделать - вы все равно получите один логический результат:

class(patientdata[,2]) == "POSIXt" 
#[1] FALSE TRUE 

inherits(patientdata[,2], "POSIXt") 
#[1] TRUE 
+0

Удивите, что вы сделали 'df <- patien tdata' часть для хотя –

+0

Я просто раздражался при наборе 'patientdata'. – nrussell

+2

В эпоху компьютеров мы, как правило, с помощью CTRL +с/CTRL +v вместо того, чтобы вручную писать вещи :) –

1

Если вы используете purrr и lubridate, вы могли бы просто написать

library(purrr) 
library(lubridate) 

patientdata %>% dmap_if(is.POSIXt, as.Date) 

который будет возвращать что-то, что выглядит так же, как оригинал, но классы изменились, как вы можете увидеть, если вы звоните str на него:

patientdata %>% dmap_if(is.POSIXt, as.Date) %>% str() 
## 'data.frame': 4 obs. of 4 variables: 
## $ patientID: num 1 2 3 4 
## $ AdmDate : Date, format: "2010-10-11" "2008-03-25" "2016-04-23" ... 
## $ diabetes : Factor w/ 2 levels "Type1","Type2": 1 2 1 2 
## $ status : Factor w/ 3 levels "Excellent","Improved",..: 3 2 1 3 

Обратите внимание, что вам нужно dmap так purrr будет сохранить список в data.frame, а версия *_if, которая принимает функцию предиката, чтобы определить, какие столбцы/элементы для вызова главной функции на.

Если вы не хотите загружать lubridate только для is.POSIXt, вы могли бы написать что то же самое

patientdata %>% dmap_if(~'POSIXt' %in% class(.x), as.Date) 

или версию dplyr:

library(dplyr) 

patientdata %>% mutate_if(function(x){'POSIXt' %in% class(x)}, as.Date) 

который с lubridate::is.POSIXt настолько хороша, как оригинал:

patientdata %>% mutate_if(is.POSIXt, as.Date) 
+0

Хм, я думаю, что ваш исходный код действительно работает, но когда я пытаюсь запустить его без str() в конце, я все еще, кажется, вижу объект POSIXt ..... мысли?patientdata%>% mutate_if (is.POSIXt, as.Date) str (patientdata) – petergensler

+0

Вам нужно связать строку 'str', то есть' patientdata%>% mutate_if (is.POSIXt, as.Date)%>% str() 'поэтому' str' вызывается в унаследованном data.frame. Если вы предпочитаете, вы можете просто сначала назначить измененный data.frame переменной, а затем вы можете вызвать 'str', как вам нравится:' patientdata2 <- patientdata%>% mutate_if (is.POSIXt, as.Date); str (patientdata2) ' – alistaire

+0

patientdata <- patientdata%>% mutate_if (is.POSIXt, as.Date) str (patientdata) - хороший синтаксис. Большое спасибо за Вашу помощь! – petergensler

Смежные вопросы