r - 使用另一个数据帧的平均值和 sd 标准化数据帧



我有一个数据帧,它存储了 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']

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

您可以定义一个作用于列的函数,并使用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

这是一个带有pivot_longer/pivot_wider的选项。 使用pivot_longer将数据重塑为"长"格式,left_join使用"mean_sd_sf"数据集,使用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 

或与Mapbase R

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

最新更新