I have a list of around 30 dataframes. I calculate various statistics (mean, sd, median, etc) on the values within each dataframe using lapply and save as a new dataframe
Each dataframe within the list of the dataframes represents chemistry information and has different requirements in how many decimal places are displayed for the the calculated statistics. I also have a requirement that if a given analyte is to be displayed to 3 decimal places then a value of 23.2 must be 23.200. I am able to set the same decimal places across all dataframes but specific to my requirements.
I can use the format function on a vector to get the decimal places I want such as
myvector <- runif(10,1,90)
newVector <- format(round(myvector ,3),nsmall = 3) #make decimal places 3
I believe the way forward is to use a list that can be somehow passed on to get the desired result.
an example of my list of dataframes below
list(Fe = structure(list(Determination_No = 1:6, `2` = c(55.94,
55.7, 56.59, 56.5, 55.98, 55.93), `3` = c(56.83, 56.54, 56.18,
56.5, 56.51, 56.34), `4` = c(56.39, 56.43, 56.53, 56.31, 56.47,
56.35), `5` = c(56.32, 56.29, 56.31, 56.32, 56.39, 56.32), `7` = c(56.48,
56.4, 56.54, 56.43, 56.73, 56.62), `8` = c(56.382, 56.258, 56.442,
56.258, 56.532, 56.264), `10` = c(56.3, 56.5, 56.2, 56.5, 56.7,
56.5), `12` = c(56.11, 56.46, 56.1, 56.35, 56.36, 56.37)), class = "data.frame", row.names = c(NA,
-6L)), SiO2 = structure(list(Determination_No = 1:6, `2` = c(7.63,
7.65, 7.73, 7.67, 7.67, 7.67), `3` = c(7.84, 7.69, 7.59, 7.77,
7.74, 7.64), `4` = c(7.67, 7.74, 7.62, 7.81, 7.66, 7.8), `5` = c(7.91,
7.84, 7.96, 7.87, 7.84, 7.92), `7` = c(7.77, 7.83, 7.76, 7.78,
7.65, 7.74), `8` = c(7.936, 7.685, 7.863, 7.838, 7.828, 7.767
), `10` = c(7.872684992, 7.851291827, 7.872684992, 7.722932832,
7.680146501, 7.615967003), `12` = c(7.64, 7.71, 7.71, 7.65, 7.82,
7.68)), class = "data.frame", row.names = c(NA, -6L)), Al2O3 = structure(list(
Determination_No = 1:6, `2` = c(2.01, 2.02, 2.03, 2.01, 2.02,
2), `3` = c(2.01, 2.01, 2, 2.02, 2.02, 2.03), `4` = c(2,
2.03, 1.99, 2.01, 2.01, 2.01), `5` = c(2.02, 2.02, 2.05,
2.03, 2.02, 2.03), `7` = c(1.88, 1.9, 1.89, 1.88, 1.88, 1.87
), `8` = c(2.053, 2.044, 2.041, 2.038, 2.008, 2.02), `10` = c(2.002830415,
2.021725042, 2.021725042, 1.983935789, 2.002830415, 2.021725042
), `12` = c(2.09, 2.05, 1.96, 2.09, 2.06, 2.02)), class = "data.frame", row.names = c(NA,
-6L)), TiO2 = structure(list(Determination_No = 1:6, `2` = c(0.07,
0.07, 0.07, 0.07, 0.07, 0.07), `3` = c(0.06, 0.06, 0.06, 0.06,
0.06, 0.06), `4` = c(0.07, 0.07, 0.07, 0.07, 0.07, 0.07), `5` = c(0.07,
0.07, 0.07, 0.07, 0.07, 0.07), `7` = c(0.07, 0.07, 0.07, 0.06,
0.07, 0.06), `8` = c(0.073, 0.07, 0.081, 0.072, 0.07, 0.071),
`10` = c(0.066721378, 0.066721378, 0.066721378, 0.066721378,
0.066721378, 0.066721378), `12` = c(0.082, 0.079, 0.073,
0.077, 0.08, 0.077)), class = "data.frame", row.names = c(NA,
-6L)), Mn = structure(list(Determination_No = 1:6, `2` = c(0.194,
0.209, 0.218, 0.22, 0.213, 0.217), `3` = c(0.222, 0.214, 0.21,
0.212, 0.205, 0.213), `4` = c(0.21, 0.21, 0.21, 0.22, 0.23, 0.2
), `5` = c(0.23, 0.21, 0.22, 0.21, 0.2, 0.22), `7` = c(0.197,
0.238, 0.205, 0.223, 0.205, 0.214), `8` = c(0.217, 0.221, 0.237,
0.213, 0.227, 0.232), `10` = c(0.21, 0.21, 0.22, 0.23, 0.21,
0.22), `12` = c(0.27, 0.24, 0.23, 0.23, 0.22, 0.23)), class = "data.frame", row.names = c(NA,
-6L)), CaO = structure(list(Determination_No = 1:6, `2` = c(0.08,
0.07, 0.07, 0.07, 0.08, 0.07), `3` = c(0.08, 0.07, 0.07, 0.07,
0.07, 0.07), `4` = c(0.07, 0.06, 0.06, 0.07, 0.06, 0.06), `5` = c(0.08,
0.07, 0.08, 0.07, 0.07, 0.07), `7` = c(0.08, 0.08, 0.07, 0.08,
0.08, 0.08), `8` = c(0.07, 0.071, 0.07, 0.067, 0.071, 0.07),
`10` = c(0.069959326, 0.069959326, 0.069959326, 0.069959326,
0.069959326, 0.069959326), `12` = c(0.09, 0.09, 0.34, 0.09,
0.09, 0.08)), class = "data.frame", row.names = c(NA, -6L
)))
I have the following function to calculate SD and set to 3 decimals places
LabSD <- function(x,...){
lab.SD <- round(mapply(sd, x[-1], na.rm = T), digits = 3)
SD.All <- unlist(x[-1]) #convert all the values to a vector
lab.SD.T <- format(round(lab.SD ,3),nsmall = 3)
lab.SD.All <- round(sd(SD.All, na.rm = T), digits = 3)
lab.SD.All.T <- format(round(lab.SD.All,3),nsmall = 3)
lab.SDSummary <- c(lab.SD.T, lab.SD.All.T)
return(lab.SDSummary)
}
Then use lapply to apply to my list of dataframes
df.LabSD <- lapply(df, function(x) LabSD(x,na.rm=T))
I have created a list of for the decimal places i want for each analyte and whether its for the mean value or standard deviation as follows
and tried calling up values but have hit a hurdle
AnalyteDecList <- c("Fe", "SiO2", "Al2O3", "TiO2", "Mn",'CaO')
decimlist <- data.frame(analytes = AnalyteDecList,
mean.dec = c(2,2,2,3,3,3), #decimal places for the mean
sd.Dec = c(3,3,3,4,4,4)) #decimal places for SD
decimlist[decimlist$analytes == "Fe" %in% decimlist$analytes,] #get the decimal places for Fe
Am I even taking the right approach? any help on how to solve my problem is greatly appreciated
Make the function such that it displays decimal places dynamically.
LabSD <- function(x, sd.Dec) {
lab.SD <- round(mapply(sd, x[-1], na.rm = T), digits = sd.Dec)
SD.All <- unlist(x[-1]) #convert all the values to a vector
lab.SD.T <- format(round(lab.SD ,sd.Dec),nsmall = sd.Dec)
lab.SD.All <- round(sd(SD.All, na.rm = T), digits = sd.Dec)
lab.SD.All.T <- format(round(lab.SD.All,sd.Dec),nsmall = sd.Dec)
lab.SDSummary <- c(lab.SD.T, lab.SD.All.T)
return(lab.SDSummary)
}
Pass it using Map
:
decimlist$sd.Dec
#[1] 3 3 3 4 4 4
Map(LabSD, df[decimlist$analytes], decimlist$sd.Dec)
#$Fe
# 2 3 4 5 7 8 10 12
#"0.355" "0.218" "0.080" "0.034" "0.125" "0.116" "0.176" "0.150" "0.210"
#$SiO2
# 2 3 4 5 7 8 10 12
#"0.033" "0.091" "0.079" "0.048" "0.060" "0.086" "0.111" "0.065" "0.097"
#$Al2O3
# 2 3 4 5 7 8 10 12
#"0.010" "0.010" "0.013" "0.012" "0.010" "0.017" "0.015" "0.049" "0.052"
#$TiO2
# 2 3 4 5 7 8 10 12
#"0.0000" "0.0000" "0.0000" "0.0000" "0.0052" "0.0042" "0.0000" "0.0031" "0.0055"
#$Mn
# 2 3 4 5 7 8 10 12
#"0.0096" "0.0056" "0.0103" "0.0105" "0.0149" "0.0092" "0.0082" "0.0175" "0.0132"
#$CaO
# 2 3 4 5 7 8 10 12
#"0.0052" "0.0041" "0.0052" "0.0052" "0.0041" "0.0015" "0.0000" "0.1030" "0.0392"
You can use the same process for displaying mean.
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.