Как я могу преобразовать матрицу строк в кусочек?
Мне даны некоторые данные в файле .rData. Формат представляет собой объект xts
в символьном режиме. (Я понимаю, что это необычный формат, но я не контролирую его)
> head(trades)
SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
2012-05-04 09:30:00 "BAC" "T" "7.89" "38538" "F" "7.89" "523" "7.9"
2012-05-04 09:30:01 "BAC" "Z" "7.885" "288" "@" "7.88" "61033" "7.9"
2012-05-04 09:30:03 "BAC" "X" "7.89" "1000" "@" "7.88" "1974" "7.89"
2012-05-04 09:30:07 "BAC" "T" "7.89" "19052" "F" "7.88" "1058" "7.89"
2012-05-04 09:30:08 "BAC" "Y" "7.89" "85053" "F" "7.88" "108101" "7.9"
2012-05-04 09:30:09 "BAC" "D" "7.8901" "10219" "@" "7.89" "268" "7.9"
> mode(trades)
'character'
Я хотел бы обработать эти данные, преобразовывая их в более чистый формат, а именно в кепку, чтобы я мог хранить столбцы как datetimes, double и integers.
Мне удалось добиться этого с помощью следующего кода:
> trades_ = bind_cols(data_frame(DATE=index(trades)), as_data_frame(coredata(trades))) %>%
mutate_at(as.numeric, .cols=vars(PRICE, BID, OFR)) %>%
mutate_at(as.integer, .cols=vars(SIZE, BIDSIZ, OFRSIZ))
> head(trades_)
# A tibble: 6 × 10
DATE SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
<dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
6 2012-05-04 09:30:09 BAC D 7.8901 10219 @ 7.89 268 7.90
Мне интересно, есть ли для этого встроенная функция. Что-то, что смотрит на каждый столбец матрицы trades
и вычисляет, является ли он столбцом целых чисел, удваивает и т.д. И преобразует его в соответствующий тип.
Это то, что сделал бы анализатор csv.
Ответы
Ответ 1
Это далеко не авторитетный ответ, но я это сделал:
smarter_type_convert = function (vector) {
converted_vector = type.convert(vector)
if (is.numeric(converted_vector)) {
int_vector = as.integer(converted_vector)
if (isTRUE(all.equal(int_vector, converted_vector, check.attributes=FALSE))) {
int_vector
} else {
converted_vector
}
} else {
converted_vector
}
}
trades %>% coredata %>% as_data_frame %>% mutate_all(smarter_type_convert)
Ответ 2
Вы правы, что фрейм данных - правильный подход, поскольку вы работаете с несколькими классами в одном и том же фрейме. xts
не допускает множественные классы, поэтому правила принуждения заставляют вас работать с символами вместо чисел.
Вот решение, поэтому вам не нужно специально вызывать каждый столбец. Я использую пакет tidyquant
, который предназначен для работы с количественными данными в пределах "tidyverse" (т.е. С использованием "аккуратных" кадров данных). Он также имеет несколько хороших функций для преобразования в и из xts
, matrix
и других классов временных рядов, содержащих имена строк.
Во-первых, я воссоздаю данные.
> trades_xts
SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
2012-05-04 09:30:00 "BAC" "T" "7.8900" "38538" "F" "7.89" "523" "7.90"
2012-05-04 09:30:01 "BAC" "Z" "7.8850" "288" "@" "7.88" "61033" "7.90"
2012-05-04 09:30:03 "BAC" "X" "7.8900" "1000" "@" "7.88" "1974" "7.89"
2012-05-04 09:30:07 "BAC" "T" "7.8900" "19052" "F" "7.88" "1058" "7.89"
2012-05-04 09:30:08 "BAC" "Y" "7.8900" "85053" "F" "7.88" "108101" "7.90"
2012-05-04 09:30:09 "BAC" "D" "7.8901" "10219" "@" "7.89" "268" "7.90"
Далее я использую аккуратные функции для очистки данных. Это немного дольше, чем ваш script, но вам не нужно беспокоиться о том, какие столбцы имеют тип данных (за исключением индекса xts). Обратите внимание, что я использую функции tidyquant::as_tibble()
для преобразования имен строк xts
в столбец. Я использую mutate_each
для применения функции type.convert
к каждому столбцу. К сожалению, база R любит класс factor
, поэтому я добавляю дополнительный шаг для преобразования в character
. Последние два этапа просто очищают столбец даты и времени, используя dplyr::rename
и lubridate::as_datetime
, который tidyquant
загружает для вас.
> library(tidyquant)
> trades_xts %>%
as_tibble(preserve_row_names = TRUE) %>%
mutate_each(funs(type.convert)) %>%
mutate_if(is.factor, as.character) %>%
rename(DATE = row.names) %>%
mutate(DATE = as_datetime(DATE, tz = Sys.timezone()))
# A tibble: 6 × 9
DATE SYMBOL EX PRICE SIZE COND BID BIDSIZ OFR
<dttm> <chr> <chr> <dbl> <int> <chr> <dbl> <int> <dbl>
1 2012-05-04 09:30:00 BAC T 7.8900 38538 F 7.89 523 7.90
2 2012-05-04 09:30:01 BAC Z 7.8850 288 @ 7.88 61033 7.90
3 2012-05-04 09:30:03 BAC X 7.8900 1000 @ 7.88 1974 7.89
4 2012-05-04 09:30:07 BAC T 7.8900 19052 F 7.88 1058 7.89
5 2012-05-04 09:30:08 BAC Y 7.8900 85053 F 7.88 108101 7.90
6 2012-05-04 09:30:09 BAC D 7.8901 10219 @ 7.89 268 7.90