Как я могу преобразовать матрицу строк в таблицу?

Мне дали некоторые данные в файле.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'

Я хотел бы обработать эти данные путем преобразования в более разумный формат, а именно в тиббл, чтобы я мог хранить столбцы как datetime, double и integer.

Мне удалось добиться этого с помощью следующего кода:

> 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.

2 ответа

Решение

Это далеко не авторитетный ответ, но в итоге я сделал это:

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)

Вы правы, что фрейм данных - правильный подход, так как вы работаете с несколькими классами в одном фрейме. 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" 

Далее я использую аккуратные функции для очистки данных. Это немного длиннее, чем ваш скрипт, но вам не нужно беспокоиться о том, какие столбцы имеют какой тип данных (за исключением индекса 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
Другие вопросы по тегам