Введите отсутствующие даты-даты в определенные ячейки файла data.frame (R) [duplicate]

Использовать Javascript Proxies

. Одна очень полезная функция Enums, которую вы получаете с традиционных языков, - это то, что они взорвутся (выкидывают ошибку времени компиляции), если вы попытаетесь получить доступ который не существует.

Помимо замораживания структуры изъеденного перечисления, чтобы предотвратить добавление дополнительных значений случайно или злонамеренно, ни один из других ответов не затрагивает эту неотъемлемую особенность Enums.

Как вы, вероятно, знаете, несуществующие члены в JavaScript просто возвращают undefined и не взорвут ваш код. Поскольку перечисления являются предопределенными константами (т.е. днями недели), никогда не должно быть случая, когда перечислитель должен быть неопределенным.

Не поймите меня неправильно, поведение JavaScript возврата undefined при доступе к неопределенным свойства на самом деле очень мощная функция языка, но это не функция, которую вы хотите, когда пытаетесь издеваться над традиционными структурами Enum.

Здесь отображаются объекты прокси. Прокси были стандартизированы на языке с введением ES6 (ES2015). Вот описание из MDN:

Объект Proxy используется для определения пользовательского поведения для основных операций (например, поиск свойств, назначение, перечисление, вызов функции и т. Д.).

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

Вот надуманный пример, который использует объект Proxy для имитации Enums. В этом примере перечислениями являются стандартные HTTP-методы (например, «GET», «POST» и т. Д.):

// Generic Factory Function for creating enums (10 lines)
// Feel free to add this to your utility library in 
// your codebase and profit! Note: As Proxies are an ES6 
// feature, some browsers/clients may not support it and 
// you may need to transpile using a service like babel

function createEnum(enumObj) {

  // Instantiating a `Proxy` object requires two parameters, 
  // a `target` object and a `handler`. We first define the handler,
  // then use the handler to instantiate a Proxy.

  // a proxy handler is simply an object whose properties
  // are functions which define the behavior of the proxy 
  // when an operation is performed on it. For enums, we 
  // need to define behavior that lets us check what enumerator
  // is being accessed. This can be done by defining the "get" trap
  
  const enumHandler = {
    get: function(target, name) {
      if (target[name]) {
        return target[name]
      }
      throw new Error(`No such enumerator: ${name}`)
    }
  }
  
  
  // Freeze the target object to prevent modifications
  return new Proxy(Object.freeze(enumObj), enumHandler)
}


// Now that we have a generic way of creating Enums, lets create our first Enum!
const httpMethods = createEnum({
  DELETE: "DELETE",
  GET: "GET",
  OPTIONS: "OPTIONS",
  PATCH: "PATCH",
  POST: "POST",
  PUT: "PUT"
})

// Sanity checks
console.log(httpMethods.DELETE) 
// logs "DELETE"

httpMethods.delete = "delete" 
// no effect due to Object.freeze, fails silently (no error thrown)

try {
  console.log(httpMethods.delete) 
} catch (e) {
  console.log("Error: ", e.message)
}
// throws an error "Uncaught Error: No such enumerator: delete"

ASIDE: Что это за прокси?

Я помню, когда я впервые начал видеть слово «прокси» всюду, это определенно не имело для меня смысла в течение длительного времени. Если это вы прямо сейчас, я думаю, что простой способ обобщить доверенных лиц - это думать о них как о программном обеспечении, учреждениях или о людях, которые выступают в качестве посредников или посредников между двумя серверами, компаниями или людьми.

9
задан Adinia 7 December 2012 в 16:02
поделиться

2 ответа

Мне нравится lubridate для простоты использования:

library(lubridate) 

# note added ugly formats below
data <- data.frame(initialDiagnose = c("14.01.2009", "9/22/2005", 
        "4/21/2010", "28.01.2010", "09.01.2009", "3/28/2005", 
        "04.01.2005", "04.01.2005", "Created on 9/17/2010", "03 01 2010"))

mdy <- mdy(data$initialDiagnose) 
dmy <- dmy(data$initialDiagnose) 
mdy[is.na(mdy)] <- dmy[is.na(mdy)] # some dates are ambiguous, here we give 
data$initialDiagnose <- mdy        # mdy precedence over dmy
data
#   initialDiagnose
#       2009-01-14
#       2005-09-22
#       2010-04-21
#       2010-01-28
#       2009-09-01
#       2005-03-28
#       2005-04-01
#       2005-04-01
#       2010-09-17
#       2010-03-01
14
ответ дан MattBagg 26 August 2018 в 10:41
поделиться
a <- as.Date(data$initialDiagnose,format="%m/%d/%Y") # Produces NA when format is not "%m/%d/%Y"
b <- as.Date(data$initialDiagnose,format="%d.%m.%Y") # Produces NA when format is not "%d.%m.%Y"
a[is.na(a)] <- b[!is.na(b)] # Combine both while keeping their ranks
data$initialDiagnose <- a # Put it back in your dataframe
data$initialDiagnose
[1] "2009-01-14" "2005-09-22" "2010-04-21" "2010-01-28" "2009-01-09" "2005-03-28" "2005-01-04" "2005-01-04" "2010-09-17" "2010-01-03"

Дополнительный подход - это предыдущий метод, адаптированный к ситуации, когда у вас есть три (или более) разных формата:

data$initialDiagnose
[1] 14.01.2009 9/22/2005  12 Mar 97  4/21/2010  28.01.2010 09.01.2009 3/28/2005 
Levels: 09.01.2009 12 Mar 97 14.01.2009 28.01.2010 3/28/2005 4/21/2010 9/22/2005

multidate <- function(data, formats){
    a<-list()
    for(i in 1:length(formats)){
        a[[i]]<- as.Date(data,format=formats[i])
        a[[1]][!is.na(a[[i]])]<-a[[i]][!is.na(a[[i]])]
        }
    a[[1]]
    }

data$initialDiagnose <- multidate(data$initialDiagnose, 
                                  c("%m/%d/%Y","%d.%m.%Y","%d %b %y"))
data$initialDiagnose
[1] "2009-01-14" "2005-09-22" "1997-03-12" "2010-04-21" "2010-01-28" "2009-01-09" "2005-03-28"
16
ответ дан plannapus 26 August 2018 в 10:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: