2015-09-01 22 views
8

Zaman biçiminde bir tarih sütunu içeren verileri okumak için readr kullanıyorum. readr'un col_types seçeneğini kullanarak doğru şekilde okuyabilirim.Neden dplyr'in mutate() zaman biçimini değiştiriyor?

library(dplyr) 
library(readr) 

sample <- "time,id 
2015-03-05 02:28:11,1674 
2015-03-03 13:10:59,36749 
2015-03-05 07:55:48,NA 
2015-03-05 06:13:19,NA 
" 

mydf <- read_csv(sample, col_types="Ti") 
mydf 
       time id 
1 2015-03-05 02:28:11 1674 
2 2015-03-03 13:10:59 36749 
3 2015-03-05 07:55:48 NA 
4 2015-03-05 06:13:19 NA 

Bu güzel. Ancak, bu sütunu dplyr ile değiştirmek istersem, zaman sütunu biçimini kaybeder.

mydf %>% mutate(time = ifelse(is.na(id), NA, time)) 
     time id 
1 1425522491 1674 
2 1425388259 36749 
3   NA NA 
4   NA NA 

Bu neden oluyor?

Bu sorunu daha önce karakter haline getirerek çalışabileceğimi biliyorum, ancak ileri geri dönüş yapmadan daha kullanışlı olur.

mydf %>% mutate(time = as.character(time)) %>% 
    mutate(time = ifelse(is.na(id), NA, time)) 

cevap

18

Aslında bu sorunu değil dplyr::mutate() neden oluyor ifelse() bu. Yani orada o var

## ifelse() strips attributes 
## This is important when working with Dates and factors 
x <- seq(as.Date("2000-02-29"), as.Date("2004-10-04"), by = "1 month") 
## has many "yyyy-mm-29", but a few "yyyy-03-01" in the non-leap years 
y <- ifelse(as.POSIXlt(x)$mday == 29, x, NA) 
head(y) # not what you expected ... ==> need restore the class attribute: 
class(y) <- class(x) 

- nitelik sıyrılması sorununa bir örneği help(ifelse) gösterilmektedir. ifelse()'u kullanmak istiyorsanız biraz fazladan iş var. İşte size ifelse() olmadan istediğiniz sonuca ulaşan iki olası yöntem. Birincisi gerçekten basit ve is.na<- kullanıyor. bu nedenle bu yolu seçin ve dplyr yöntemle devam etmek istiyorum istemiyorsanız

## mark 'time' as NA if 'id' is NA 
is.na(mydf$time) <- is.na(mydf$id) 

## resulting in 
mydf 
#     time id 
# 1 2015-03-05 02:28:11 1674 
# 2 2015-03-03 13:10:59 36749 
# 3    <NA> NA 
# 4    <NA> NA 

, sen replace() yerine ifelse() kullanabilirsiniz.

mydf %>% mutate(time = replace(time, is.na(id), NA)) 
#     time id 
# 1 2015-03-05 02:28:11 1674 
# 2 2015-03-03 13:10:59 36749 
# 3    <NA> NA 
# 4    <NA> NA 

veri:

mydf <- structure(list(time = structure(c(1425551291, 1425417059, 1425570948, 
1425564799), class = c("POSIXct", "POSIXt"), tzone = ""), id = c(1674L, 
36749L, NA, NA)), .Names = c("time", "id"), class = "data.frame", row.names = c(NA, 
-4L)) 
İlgili konular