0
votes

Currently I'm learning to use R for simple financial calculations. I have seven data frames and I'm trying to apply the same function to all of them. The vector names are the same for all dfs starting with "Date" and are initially "chars". I managed to convert every "Date" vector to the date format with:

listOf <- c(Invesco2, Lyxor1, Lyxor2, ComStage, Ossiam, SPDR, Vanguard) # list of dfs
for (i in listOf){
  i[1] <- as.Date(i[1], "%d-%m-%y")
}

Now I'm trying to change the rest of vectors to numeric with again a for loop and "lapply":

lapply(listOf, as.numeric)

The console just prints all the vectors and gives 37 errors: "In lapply(listOf, as.numeric) : NAs introduced by coercion"

for (i in listOf){
  i <- as.numeric(i)
}

Again 37 Errors: In as.numeric(i) : NAs introduced by coercion In both cases nothing changed. Pls help

EDIT: There is a sample a the data set:

# Create the sample vectors
Date <- c("23-01-19", "24-01-19", "25-01-19", "26-01-19", "27-01-19" )
Open <- c("69.849998", "69.440002", "69.540001", "70.32", "69.559998")
High <- c("69.849998", "69.440002", "69.540001", "70.32", "69.559998")
Low <- c("69.849998", "69.440002", "69.540001", "70.32", "69.559998")
Close <- c("69.849998", "69.440002", "69.540001", "70.32", "69.559998")
Adj_Close <- c("69.849998", "69.440002", "69.540001", "70.32", "69.559998")
Volume <- c("0", "0", "0", "0","0")

# Create df
InvescoDf <- data.frame(Date, Open, High, Low, Close, Adj_Close, Volume)

# Create another df
OssiamDf <- InvescoDf

# Put in list together
new_list <- list(InvescoDf, OssiamDf)

EDIT 2: It creates factors. In the orginal data the vectors are chars.

EDIT 3:

  Date     Open      High      Low       Close     `Adj Close` Volume
  <chr>    <chr>     <chr>     <chr>     <chr>     <chr>       <chr> 
1 23-01-19 69.849998 69.849998 69.849998 69.849998 69.849998   0     
2 24-01-19 69.440002 69.440002 69.440002 69.440002 69.440002   0     
3 25-01-19 69.540001 69.540001 69.540001 69.540001 69.540001   0     
4 28-01-19 70.32     70.32     70.32     70.32     70.32       0     
5 29-01-19 69.559998 69.559998 69.559998 69.559998 69.559998   0     
6 30-01-19 69.580002 69.580002 69.580002 69.580002 69.580002   0  

BR Toni

2

2 Answers

1
votes

If we are creating a list, use

listOf <- list(Invesco2, Lyxor1, Lyxor2, ComStage, Ossiam, SPDR, Vanguard) 

Each data.frame inside the list is also a list with columns of equal length and as.numeric can be applied to vectors. So, we need to loop over the data.frame inside the list i.e a double lapply is needed

new_list <- lapply(new_list, function(dat) {
            dat[[1]] <- as.Date(dat[[1]], "%d-%m-%y")
            dat[-1] <- lapply(dat[-1],  function(x) as.numeric(as.character(x)))
            dat
      })
str(new_list)
#List of 2
# $ :'data.frame':  5 obs. of  7 variables:
#  ..$ Date     : Date[1:5], format: "2019-01-23" "2019-01-24" "2019-01-25" "2019-01-26" ...
#  ..$ Open     : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ High     : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Low      : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Close    : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Adj_Close: num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Volume   : num [1:5] 0 0 0 0 0
# $ :'data.frame':  5 obs. of  7 variables:
#  ..$ Date     : Date[1:5], format: "2019-01-23" "2019-01-24" "2019-01-25" "2019-01-26" ...
#  ..$ Open     : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ High     : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Low      : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Close    : num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Adj_Close: num [1:5] 69.8 69.4 69.5 70.3 69.6
#  ..$ Volume   : num [1:5] 0 0 0 0 0

Or another option is

new_list <- lapply(new_list,  function(dat) {
                  dat <- type.convert(dat, as.is = TRUE)
                  dat[[1]] <- as.Date(dat[[1]], "%d-%m-%y")
                  dat
                })
names(new_list) <- c('InvescoDf', 'OssiamDf')
list2env(new_list, .GlobalEnv)
0
votes

Here is another option. This takes the list, converts the date to date, then converts anything that is character to numeric across the list of dataframes.

library(tidyverse)

new_list %>%
  map(., 
         ~mutate(.x, Date = lubridate::dmy(Date)) %>%
           mutate_if(is.character, as.numeric)
      )
#> [[1]]
#>         Date  Open  High   Low Close Adj_Close Volume
#> 1 2019-01-23 69.85 69.85 69.85 69.85     69.85      0
#> 2 2019-01-24 69.44 69.44 69.44 69.44     69.44      0
#> 3 2019-01-25 69.54 69.54 69.54 69.54     69.54      0
#> 4 2019-01-26 70.32 70.32 70.32 70.32     70.32      0
#> 5 2019-01-27 69.56 69.56 69.56 69.56     69.56      0
#> 
#> [[2]]
#>         Date  Open  High   Low Close Adj_Close Volume
#> 1 2019-01-23 69.85 69.85 69.85 69.85     69.85      0
#> 2 2019-01-24 69.44 69.44 69.44 69.44     69.44      0
#> 3 2019-01-25 69.54 69.54 69.54 69.54     69.54      0
#> 4 2019-01-26 70.32 70.32 70.32 70.32     70.32      0
#> 5 2019-01-27 69.56 69.56 69.56 69.56     69.56      0