R - Неожиданное поведение при проверке типов столбцов Tidyverse кадра данных - PullRequest
1 голос
/ 05 марта 2020

Я работаю с некоторыми данными, имеющими сотни ковариат, поэтому я решил написать некоторые функции, чтобы сделать предварительную обработку намного быстрее и чище (например, масштабирование определенных числовых переменных c). Важной частью всех этих функций является проверка типов столбцов перед тем, как применить к ним определенную функцию.

Вот моя функция для масштабирования непрерывных столбцов:

# rm (vector): names of columns not to be scaled
scale.continuous <- function(df, rm=NULL) {
  cols <- setdiff(colnames(df), rm)
  for(col in cols) {
    if(is.numeric(df[,col])){
      df[,col] <- as.numeric(scale(df[,col]))
    }
  }
  df
}

Это прекрасно работает хорошо, если я загружаю фрейм данных, используя read.csv(), но у меня есть огромные данные, поэтому увеличение скорости использования read_csv() из readr / tidyverse является значительным. К сожалению, если я загружаю свои данные, используя read_csv(), все мои функции прерываются.

Я сузил проблему до проверки типов, особенно при проверке типов столбца, к которому я получаю доступ с помощью строки имя его столбца . Вот некоторый код, чтобы продемонстрировать, что я имею в виду:

# When using read.csv()
> is.numeric(df$col)
[1] TRUE
> is.numeric(df[,"col"])
[1] TRUE

# When using read_csv()
> is.numeric(df$col)
[1] TRUE
> is.numeric(df[,"col"])
[1] FALSE

Я понял, что проблема здесь заключалась в том, что при индексации кадра данных строкой, как я делаю выше, вместо обычного списка возвращается тиббл, как это делают другие методы индексации. , Я не понимаю, почему такое поведение существует, почему as.numeric() (или любая проверка типов) не работает с тибблом и вообще почему существует такое различие в способе построения стандартных и временных блоков данных. Кроме того, было бы неплохо узнать, есть ли параметр, который я могу изменить в read_csv(), который сделает поведение этого типа индексации таким же, как и для стандартного фрейма данных.


Я должен упомянуть Я понимаю, что, возможно, есть лучшие способы написания этого кода (например, просто использовать df$"col" для индексации, чтобы решить проблему), но я все еще не понимаю, что было root проблемы с моим первым подходом. Сейчас я работаю с гораздо большими наборами данных, которые требуют гораздо более сложной предварительной обработки, чем та, к которой я привык в прошлом, поэтому я хочу максимально полно понять структуры данных, которые я использую.

1 Ответ

0 голосов
/ 05 марта 2020

Tibbles имеют немного другое поведение по умолчанию, чем обычные кадры данных при использовании функции извлечения [, которая может быть немного затруднительной. В частности, df[,"col"] для таблицы возвращает столбец с одним столбцом, тогда как для обычного фрейма данных он возвращает вектор. Поэтому вам нужно использовать:

df[["col"]]

Или явно указать, что вы хотите привести к наименьшему измерению, и выполнить:

df[, "col", drop = TRUE]

Из документации:

df [, j] возвращает столбик; это не автоматически извлекает столбец внутри. df [, j, drop = FALSE] является значением по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...