简体   繁体   中英

Apply as.numeric on a list of data.frames

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

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM