【问题标题】:Apply different rounding rules to each dataframe in a list of dataframes R对数据框列表中的每个数据框应用不同的舍入规则 R
【发布时间】:2021-07-22 16:38:48
【问题描述】:

我有一个大约 30 个数据框的列表。我使用 lapply 计算每个数据帧内的值的各种统计数据(平均值、标准差、中位数等)并保存为新数据帧

数据框列表中的每个数据框都代表化学信息,并且对计算的统计数据显示的小数位数有不同的要求。我还有一个要求,如果给定的分析物要显示到小数点后 3 位,那么 23.2 的值必须是 23.200。我可以在所有数据帧中设置相同的小数位,但具体到我的要求。

我可以在向量上使用格式函数来获得我想要的小数位,例如

myvector <- runif(10,1,90)
newVector <- format(round(myvector ,3),nsmall = 3) #make decimal places 3

我相信前进的道路是使用可以通过某种方式传递的列表来获得所需的结果。

下面是我的数据框列表示例

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

我有以下函数来计算 SD 并设置为小数点后 3 位

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

然后使用 lapply 应用到我的数据框列表

df.LabSD <- lapply(df, function(x) LabSD(x,na.rm=T))

我已经为每个分析物创建了一个我想要的小数位列表,以及它是平均值还是标准偏差,如下所示

并尝试调用值但遇到了障碍

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

我是否采取了正确的方法? 非常感谢任何有关如何解决我的问题的帮助

【问题讨论】:

    标签: r list dataframe lapply


    【解决方案1】:

    使函数动态显示小数位。

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

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

    您可以使用相同的过程来显示平均值。

    【讨论】:

    • 再次感谢。假设我在联合函数(可能还有许多其他函数)中同时应用了均值和 SD,并返回了一个列表。我可以将多个小数位规则映射到返回的所有统计信息吗?
    • 是的,你可以这样做。您可以更改函数以同时接受小数 LabSD &lt;- function(x, sd.Dec, mean.dc) {...} 使用 sd.dec 表示 sdmean.dc 表示平均值。在Map 你可以做Map(LabSD, df[decimlist$analytes], decimlist$sd.Dec, decimlist$mean.dec)
    猜你喜欢
    • 2019-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2021-07-28
    相关资源
    最近更新 更多