I have example data as follows:
library(data.table)
set.seed(1)
DT <- data.table(panelID = sample(50,50), # Creates a panel ID
Country = c(rep("Albania",30),rep("Belarus",50), rep("Chilipepper",20)),
some_NA = sample(0:5, 6),
some_NA_factor = sample(0:5, 6),
Group = c(rep(1,20),rep(2,20),rep(3,20),rep(4,20),rep(5,20)),
Time = rep(seq(as.Date("2010-01-03"), length=20, by="1 month") - 1,5),
wt = 15*round(runif(100)/10,2),
Income = round(rnorm(10,-5,5),2),
Happiness = sample(10,10),
Sex = round(rnorm(10,0.75,0.3),2),
Age = sample(100,100),
Educ = round(rnorm(10,0.75,0.3),2))
DT [, uniqueID := .I] # Creates a unique ID # https://stackoverflow.com/questions/11036989/replace-all-0-values-to-na
DT$some_NA_factor <- factor(DT$some_NA_factor)
DT$Group <- as.character(DT$Group)
The second DT, DT2
, is just a copy of DT
with one additional change in the Group
column, namely a string value.
DT2 <- copy(DT)
DT2[2,5] <- "something"
What I want to do, to convert columns (in this case colum 5 Group
) to numeric if that is possible for most values. The (already working) code to do this is as follows:
# Put object names in the environment in a vector
dfs <- ls()
conv_to_num_check <- function(z) is.character(z) && (mean(grepl("^ *-?[\\d.]+(?:e-?\\d+)?$", z, perl = TRUE), na.rm=TRUE)>0.9)
for (i in seq_along(dfs)) {
fetch_cols <- which(sapply(get(dfs[i]), conv_to_num_check))
setDT(get(dfs[i]))[, (fetch_cols) := lapply(.SD, as.numeric), .SDcols = fetch_cols]
}
But because I thought this might go wrong (because of non data.frames in the environment), I put it in a tryCatch
. The behaviour of the tryCatch
is however not as I expected, because it ends up not changing DT2
.
for (i in seq_along(dfs)) {
tryCatch(
expr = {
fetch_cols <- which(sapply(get(dfs[i]), conv_to_num_check))
print(paste0("The following columns of ", dfs[i], " will be converted (named interger (0) = no columns converted)"))
print(fetch_cols)
print("BEFORE")
print(str(get(dfs[i])))
setDT(get(dfs[i]))[, (fetch_cols) := lapply(.SD, as.numeric), .SDcols = fetch_cols]
print("AFTER")
print(str(get(dfs[i])))
}, error = function(e){ #Do this if an error is caught...
}, warning = function(w){ # Do this if an warning is caught...
}, finally = {# Do this at the end before quitting the tryCatch structure.
}
)
}
Could someone explain to me why this is the case?
Is there a better way to make sure that my code does not crash?