почему происходит сбой функции `mutate_all ()` при чтении фрейма данных на основе `xlsx`? - PullRequest
0 голосов
/ 28 апреля 2018

У меня есть фрейм данных (df), который я изначально прочитал из xlsx документа. Я пытаюсь создать новый df со всеми отсутствующими значениями, замененными на 999999. Когда я запускаю следующую команду:

LPAv0.4.2 <- LPAv0.3 %>% mutate_all(funs(replace(., is.na(.), 999999)))

Я получаю следующую ошибку:

13. stop(structure(list(message = "Evaluation error: 'origin' must be supplied.", call = mutate_impl(.data, dots), cppstack = NULL), .Names = c("message", "call", "cppstack"), class = c("Rcpp::eval_error", "C++Error", "error", "condition")))
12. mutate_impl(.data, dots)
11. mutate.tbl_df(.tbl, !(!(!funs)))
10. mutate(.tbl, !(!(!funs)))
9. mutate_all(., funs(replace(., is.na(.), 999999)))
8. function_list[[k]](value)
7. withVisible(function_list[[k]](value))
6. freduce(value, `_function_list`)
5. `_fseq`(`_lhs`)
4. eval(expr, envir, enclos)
3. eval(quote(`_fseq`(`_lhs`)), env, env)
2. withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
1. LPAv0.3 %>% mutate_all(funs(replace(., is.na(.), 999999)))

Странно то, что если я записываю LPAv0.3 в csv, а затем снова читаю его, команда LPAv0.4.2 <- LPAv0.3 %>% mutate_all(funs(replace(., is.na(.), 999999))) работает как положено. Однако, если я записываю в файл xlsx, а затем снова читаю, он снова завершается с ошибкой, указанной выше.

Есть идеи, почему это происходит? Кроме того, есть идеи, как я могу заменить все отсутствующие значения без необходимости печатать из R, а затем импортировать его обратно?

Заранее спасибо.


сообщение об ошибке

Error in as.POSIXct.numeric(value) : 'origin' must be supplied

    16. stop("'origin' must be supplied")
    15. as.POSIXct.numeric(value)
    14. as.POSIXct(value)
    13. `[<-.POSIXct`(`*tmp*`, thisvar, value = 99999)
    12. `[<-`(`*tmp*`, thisvar, value = 99999)
    11. `[<-.data.frame`(`*tmp*`, list, value = 99999)
    10. `[<-`(`*tmp*`, list, value = 99999)
    9. replace(., is.na(.), 99999)
    8. function_list[[k]](value)
    7. withVisible(function_list[[k]](value))
    6. freduce(value, `_function_list`)
    5. `_fseq`(`_lhs`)
    4. eval(expr, envir, enclos)
    3. eval(quote(`_fseq`(`_lhs`)), env, env)
    2. withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
    1. LPAv0.3 %>% replace(., is.na(.), 99999)

Ответы [ 4 ]

0 голосов
/ 28 апреля 2018

Ошибка ниже из-за отсутствия значения в столбце POSIXct.

Ошибка в as.POSIXct.numeric (значение): необходимо указать 'origin'

Так что вы можете попробовать что-то вроде этого. Здесь я исключил все POSIXct столбцы, чтобы заменить оставшиеся столбцы NA на 999999

library(tidyverse)
library(lubridate)

LPAv0.3 %>% 
  mutate_at(vars(-one_of(names(.)[sapply(., is.POSIXct)])), funs(replace(., is.na(.), 999999)))
0 голосов
/ 28 апреля 2018

Столбцы даты в вашем файле читаются как переменная POSIXct в readxls. Если вы записываете это в CSV и читаете снова, этот столбец читается как фактор (или символ, если вы используете stringsAsFactors = FALSE). Если у вас есть пропущенные значения в столбце с классом POSIX или Date, вам необходимо тщательно продумать, на что вы их заменяете. Если вы замените отсутствующие значения на 999999, их необходимо преобразовать в значение даты, которое, в свою очередь, требует источника. Любой метод, который вы используете, вызовет проблемы с этим. Если у вас нет пропущенных значений в столбцах даты (как в примере данных), но они ограничены другими (числовыми или текстовыми) столбцами, тогда простое решение:

LPAv0.4.2 <- LPAv0.3
LPAv0.4.2 [is.na(LPAv0.4.2 )] <- 999999

Вам не нужно использовать глагол tidyverse для всего :-) Я признателен, что не полностью отвечаю на ваш вопрос относительно ПОЧЕМУ код, который вы дали, выдает ошибку, даже если отсутствуют пропущенные значения даты. Кстати, будучи частью tidyverse, readxls даст вам толчок, тогда как read.csv даст вам нормальный фрейм данных. Это не будет иметь значения в этом случае, но я подумал, что просто укажу это на случай, если это вызовет другие проблемы, например, с индексацией.

0 голосов
/ 28 апреля 2018

Спасибо за коллективные мозги - я действительно оценил это.

Итак, я использовал следующую строку из этого поста , ссылающуюся mutate_if:

LPAv0.4.2 <- LPAv0.3 %>% mutate_if(is.numeric, funs(if_else(is.na(.), 999, .))) 

И все работает как положено. Я ценю весь вклад. Спасибо всем за то, что позволили мне передать некоторые знания!

С уважением,

Атанас.

0 голосов
/ 28 апреля 2018

То, что вы ищете, это строка:

LPAv0.4.2 <- LPAv0.3 %>% replace(., is.na(.), 99999)

Позвольте мне немного объяснить это, пока мы здесь.

Во-первых, стандартные функции R и readxl не могут записывать файлы .xlsx (несмотря на то, что сам Excel может читать различные форматы). Тем не менее, пакет readxl имеет функцию write_excel_csv, которая должна записать .csv в вашу локаль, чтобы Excel без проблем ее обнаружил.

Стандартные функции R и readxl не полагаются на имя файла, который вы указали, они используют его просто в качестве идентификатора и записывают или читают данные в (из) этого файла по определенному шаблону. Вы можете проверить это самостоятельно - переименование файла .xlsx в .csv не даст вам ничего, кроме ошибки, когда вы попытаетесь открыть его в Excel.

Функции чтения файлов предполагают, что вы заранее знаете формат файла и будете использовать соответствующую функцию. В вашем случае для чтения файла Excel (.xlsx) вам необходимо использовать функцию read_excel из пакета readxl.

...