Как я могу получить год и месяц, когда день недействителен, не фиксируя день сам? - PullRequest
4 голосов
/ 10 октября 2011

У меня есть данные, которые выглядят примерно так:

require(zoo)

X <- rbind(c(date='20111001', fmt='%Y%m%d'),
            c('20111031', '%Y%m%d'),
            c('201110', '%Y%m'),
            c('102011', '%m%Y'),
            c('31/10/2011', '%d/%m/%Y'),
            c('20111000', '%Y%m%d'))
print(X)

#      date       fmt     
# [1,] "20111001" "%Y%m%d"
# [2,] "20111031" "%Y%m%d"
# [3,] "201110"   "%Y%m"  
# [4,] "102011"   "%m%Y"  
# [5,] "31/10/2011" "%d/%m/%Y"
# [6,] "20111000" "%Y%m%d"

Я хочу только год и месяц. Мне не нужен день, поэтому я не волнуюсь, что последний день недействителен. R, к сожалению, составляет:

mapply(as.yearmon, X[, 'date'], X[, 'fmt'], SIMPLIFY=FALSE)

# $`20111001`
# [1] "Oct 2011"

# $`20111031`
# [1] "Oct 2011"

# $`201110`
# [1] "Oct 2011"

# $`102011`
# [1] "Oct 2011"

# $`31/10/2011`
# [1] "Oct 2011"

# $`20111000`
# Error in charToDate(x) : 
#   character string is not in a standard unambiguous format

Я знаю, что обычный ответ - исправить дневную часть даты, например, используя paste(x, '01', sep=''). Я не думаю, что это сработает, потому что я заранее не знаю, какой будет формат даты, и поэтому я не могу установить день без предварительного преобразования в какой-либо объект даты.

Ответы [ 3 ]

5 голосов
/ 10 октября 2011

Предполагая, что месяц всегда следует за годом и всегда состоит из двух символов в вашем date. Почему бы просто не извлечь информацию с помощью substr. Возможно что-то вроде:

lapply(X[,'date'], 
  function(x) paste(month.abb[as.numeric(substr(x, 5, 6))], substr(x, 1, 4))
  )
3 голосов
/ 10 октября 2011

Вам не нужно указывать день в своем формате, если он вам не нужен. Внимательно прочитайте ?strptime. Второй абзац в разделе «Подробности» гласит:

Каждая входная строка обрабатывается настолько, насколько необходимо для указанного формата: любой завершающие символы игнорируются.

Так что настройте свой формат, и все должно работать.

X <- rbind(c(date='20111001', fmt='%Y%m'),
           c('20111031', '%Y%m'),
           c('201110',   '%Y%m'),
           c('102011',   '%m%Y'),
           c('20111000', '%Y%m'))
mapply(as.yearmon, X[, 'date'], X[, 'fmt'], SIMPLIFY=FALSE)
0 голосов
/ 14 октября 2011

Предполагая, что мне всегда дают дату (а не время), и что любой незаконный «день» меньше 61, я могу гарантировать законную дату следующим образом, рассматривая предоставленный день как «секунды» изамена предоставленного дня на 1-й.

require(stringr)

safe_date <- str_c('01', X[, 'date'])
safe_fmt <- str_c('%d', str_replace(X[, 'fmt'], '%d', '%S'))

mapply(as.yearmon, safe_date, safe_fmt, SIMPLIFY=FALSE)

# $`0120111001`
# [1] "Oct 2011"

# $`0120111031`
# [1] "Oct 2011"

# $`01201110`
# [1] "Oct 2011"

# $`01102011`
# [1] "Oct 2011"

# $`0131/10/2011`
# [1] "Oct 2011"

# $`0120111000`
# [1] "Oct 2011"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...