2

您好,我正在尝试编写一个接收数据帧的函数,它将所有 POSIXct 或 POSIXlt 类型转换为 R 中的 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 = "/"))
}

get data 函数似乎可以工作,但我不确定如何从 getdata 中获取每个元素并将其转换为 R 中的 Date 类。谢谢!

4

2 回答 2

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
于 2016-08-06T19:43:18.023 回答
2

如果你使用purrrand lubridate,你可以写

library(purrr)
library(lubridate)

patientdata <- data.frame(
    patientID = c(1, 2, 3, 4),
    AdmDate = as.POSIXct(c("2010-10-11", "2008-03-25", "2016-04-23", "2011-06-12")),
    diabetes = c("Type1", "Type2", "Type1", "Type2"),
    status = c("Poor", "Improved", "Excellent", "Poor")
)

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

这将返回看起来与原始内容相同的内容,但是如果您调用str它,您可以看到类已更改:

patientdata %>% modify_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

请注意,您需要将列表保留为 data.frame 和modify版本,该版本采用谓词函数来确定要在哪些列/元素上调用主函数。purrr*_if

如果您不想lubridate仅使用 for is.POSIXt,则可以等效地编写

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

dplyr版本:

library(dplyr)

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

lubridate::is.POSIXt原版一样好:

patientdata %>% mutate_if(is.POSIXt, as.Date)
于 2016-08-06T20:41:47.040 回答