2017-02-27 114 views
1

我在.rData文件中给出了一些数据。格式是字符模式下的xts对象。 (I意识到这是一个不寻常的格式,但我有在它没有控制)如何将字符串矩阵转换为粗体?

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

我想通过转换成理智格式,即tibble来处理这些数据,这样我可以存储该列作为日期时间,双打和整数。

我设法用下面的代码来实现这一目标:

> 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

'?type.convert',这是因为你猜到了,作为''read.csv'等read.table'你 – thelatemail

+0

可能会更好过明确设置类型这样的辅助函数。当计算机猜错时追踪错误可能是一个痛苦。 –

+0

@HongOoi:我认为你可能是对的,'type.convert'不喜欢''SIZE'列中的''1e + 05'' ... – user357269

回答

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) 
0

你说的没错,一个数据帧是正确的做法,因为你正在使用多个类在同一个框架工作。 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_eachtype.convert函数应用于每列。不幸的是,基地R喜欢factor类,所以我添加了一个额外的步骤转换为character。最后两个步骤仅使用dplyr::renamelubridate::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