2017-02-27 2 views
1

Je reçois des données dans un fichier .rData. Le format est un objet xts en mode caractère. (Je me rends compte que c'est un format inhabituel, mais je n'ai aucun contrôle sur elle)Comment puis-je convertir une matrice de chaînes en un fichier?

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

Je voudrais traiter ces données en convertissant en un format Saner, à savoir un Tibble, pour que je puisse stocker les colonnes que datetimes, doubles et entiers.

J'ai réussi à y parvenir avec le code suivant:

> 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 

Je me demande s'il y a déjà une fonction intégrée pour cela. Quelque chose qui regarde chaque colonne de la matrice trades et détermine s'il s'agit d'une colonne d'entiers, doubles, etc et le convertit au type approprié.

C'est le genre de chose qu'un analyseur csv ferait.

+2

'? Type.convert', qui est comme vous l'aurez deviné, utilisé comme une fonction d'assistance pour les' 'read.csv' read.table' etc. – thelatemail

+0

Vous êtes probablement mieux fixer explicitement les types comme celui-ci . Le suivi des bogues lorsque l'ordinateur devine mal peut être une douleur. –

+0

@HongOoi: Je pense que vous pourriez avoir raison, 'type.convert' n'a pas aimé' "1e + 05" 'dans la colonne' SIZE' ... – user357269

Répondre

1

C'est loin d'être une réponse faisant autorité, mais je fini par faire ceci:

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

Vous avez raison qu'une trame de données est la bonne approche puisque vous travaillez avec plusieurs classes dans le même cadre. xts n'autorise pas plusieurs classes, les règles de contrainte vous obligent donc à utiliser des caractères au lieu de chiffres.

Voici une solution pour que vous n'ayez pas besoin d'appeler spécifiquement chaque colonne. J'utilise le paquet tidyquant qui est fait pour travailler avec des données quantitatives dans le "tidyverse" (c'est-à-dire en utilisant des trames de données "rangées"). Il a également quelques bonnes fonctions à convertir vers et à partir de xts, matrix et d'autres classes de séries temporelles qui contiennent des noms de lignes.

D'abord, je recréer les données.

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

Ensuite, j'utilise des fonctions propres pour nettoyer les données. C'est un peu plus long que votre script, mais vous n'avez pas à vous soucier des colonnes qui ont quel type de données (à l'exception de l'index xts). Notez que j'utilise les fonctions tidyquant::as_tibble() pour convertir les noms de ligne xts en colonne. J'utilise mutate_each pour appliquer la fonction type.convert à chaque colonne. Malheureusement, la base R aime la classe factor donc j'ajoute une étape supplémentaire pour la convertir en character. Les deux dernières étapes nettoient simplement la colonne date-heure en utilisant dplyr::rename et lubridate::as_datetime, qui charge tidyquant pour vous.

> 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