【问题标题】:Standardising dataframe using mean and sd from another dataframe使用来自另一个数据帧的均值和 sd 标准化数据帧
【发布时间】:2020-11-02 23:08:58
【问题描述】:

我有一个数据框,其中存储了 4 个(或任意 N 个)变量的平均值和标准差

mean_sd_df <- data.frame(variable = c('x1', 'x2', 'x3', 'x4'),
                         mean_var = c(2, 3, 4, 8),
                         sd_var = c(0.2, 0.3, 0.4, 0.6))

我有另一个数据框,其中包含上述四个变量的值,需要使用上述数据框中的均值和 sd 进行标准化

set.seed(123)  

dat.mat <- data.frame(x1 = sample(1:10, 4),
                      x2 = sample(1:10, 4),
                      x3 = sample(1:10, 4),
                      x4 = sample(1:10, 4))
  

这就是我进行标准化的方式。

dat.mat[ , 1] <- (dat.mat[ , 1] - mean_sd_df[1, 'mean_var'])/mean_sd_df[1, 'sd_var']
dat.mat[ , 2] <- (dat.mat[ , 2] - mean_sd_df[2, 'mean_var'])/mean_sd_df[2, 'sd_var']
dat.mat[ , 3] <- (dat.mat[ , 3] - mean_sd_df[3, 'mean_var'])/mean_sd_df[3, 'sd_var']
dat.mat[ , 4] <- (dat.mat[ , 4] - mean_sd_df[4, 'mean_var'])/mean_sd_df[4, 'sd_var']

如果我有很多变量,这可能会变大,所以想知道是否有更简单的方法来做到这一点?

【问题讨论】:

    标签: r matrix dplyr apply


    【解决方案1】:

    这是pivot_longer/pivot_wider 的选项。使用pivot_longer 将数据重新整形为“长”格式,使用“mean_sd_sf”数据集将left_join 整形为“长”格式,使用pivot_wider 进行标准化并重新整形为“宽”格式

    library(dplyr)
    library(tidyr)
    dat.mat %>%
        mutate(rn = row_number()) %>% 
        pivot_longer(cols = -rn) %>% 
        left_join(mean_sd_df, by = c('name' = 'variable')) %>% 
        transmute(rn, name, value = (value - mean_var)/sd_var) %>% 
        pivot_wider(names_from = name, values_from = value) %>% 
        select(-rn)
    # A tibble: 4 x 4
    #     x1    x2    x3     x4
    #  <dbl> <dbl> <dbl>  <dbl>
    #1     5 10      5    -5   
    #2    40  6.67  12.5  -8.33
    #3     0  3.33  -5     1.67
    #4    30 23.3   -2.5 -11.7 
    

    或者在base RMap

    dat.mat[] <- Map(function(x, y, z) (x - y)/z, dat.mat, 
               mean_sd_df$mean_var, mean_sd_df$sd_var)
    

    【讨论】:

      【解决方案2】:

      您可以定义一个作用于列的函数并使用lapply 在所有列上运行它:

      standardize <- function(col, df, mean_sd_df){
            ind_row <- which(mean_sd_df$variable == col)
            df[[col]] <- (df[[col]] - mean_sd_df[ind_row, "mean_var"])/mean_sd_df[ind_row, "sd_var"]
            return(df[[col]])
          }
          
      dat.mat <- as.data.frame(lapply(names(dat.mat), standardize,
      df=dat.mat,
      mean_sd_df=mean_sd_df),
      col.names = names(dat.mat))
      

      输出

      x1        x2   x3         x4
      1  5 10.000000  5.0  -5.000000
      2 40  6.666667 12.5  -8.333333
      3  0  3.333333 -5.0   1.666667
      4 30 23.333333 -2.5 -11.666667
      

      【讨论】:

        猜你喜欢
        • 2016-12-20
        • 2021-01-26
        • 1970-01-01
        • 2019-08-06
        • 2021-08-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多