【问题标题】:Performing arithmetic across data frames (tibbles)跨数据帧(小标题)执行算术
【发布时间】:2022-01-01 13:07:36
【问题描述】:

有没有办法将df 中的每个变量(abc)值乘以其相应的组平均值并除以df_summary 中的标准差。我想在没有硬编码的情况下做到这一点?谢谢

library(tidyverse)

set.seed(1)

df <- tibble(a = rnorm(10),
             b = rnorm(10),
             c = rnorm(10)) %>% 
  mutate(group = c(rep(1, 5), rep(2, 5)),
         .before = "a")

df_summary <- df %>% 
  group_by(group) %>% 
  summarise(across(.cols = everything(),
                   .fns = list(mean = mean, 
                               sd = sd),
                   .names = "{.col}_{.fn}")) %>% 
  ungroup()

df 
#> # A tibble: 10 × 4
#>    group      a       b       c
#>    <dbl>  <dbl>   <dbl>   <dbl>
#>  1     1 -0.626  1.51    0.919 
#>  2     1  0.184  0.390   0.782 
#>  3     1 -0.836 -0.621   0.0746
#>  4     1  1.60  -2.21   -1.99  
#>  5     1  0.330  1.12    0.620 
#>  6     2 -0.820 -0.0449 -0.0561
#>  7     2  0.487 -0.0162 -0.156 
#>  8     2  0.738  0.944  -1.47  
#>  9     2  0.576  0.821  -0.478 
#> 10     2 -0.305  0.594   0.418

df_summary
#> # A tibble: 2 × 7
#>   group a_mean  a_sd b_mean  b_sd  c_mean  c_sd
#>   <dbl>  <dbl> <dbl>  <dbl> <dbl>   <dbl> <dbl>
#> 1     1  0.129 0.961 0.0381 1.50   0.0812 1.20 
#> 2     2  0.135 0.669 0.460  0.465 -0.349  0.705

reprex package (v2.0.1) 于 2021 年 11 月 23 日创建

【问题讨论】:

    标签: r dataframe tidyverse tibble


    【解决方案1】:

    这可能会有所帮助。

    library(dplyr)
    df %>%
      group_by(group) %>%
      mutate(across(everything(), ~.x * mean(.x)/sd(.x)))
    
       group       a        b        c
       <dbl>   <dbl>    <dbl>    <dbl>
     1     1 -0.0843  0.0385   0.0622 
     2     1  0.0247  0.00992  0.0529 
     3     1 -0.112  -0.0158   0.00504
     4     1  0.215  -0.0563  -0.135  
     5     1  0.0443  0.0286   0.0419 
     6     2 -0.166  -0.0444   0.0278 
     7     2  0.0985 -0.0160   0.0771 
     8     2  0.149   0.933    0.728  
     9     2  0.116   0.812    0.237  
    10     2 -0.0617  0.587   -0.207  
    

    变得很乱

    library(tidyverse)
    
    df2 <- df_summary %>%
      melt(id.vars = "group") %>%
      separate(variable, sep = "_", into = c("variable", "func")) %>%
      pivot_wider(id_cols = c(group, variable), names_from = func, values_from = value)
      
    df %>%
      melt(id.vars = "group") %>%
      left_join(df2, by = c("group", "variable")) %>%
      mutate(value = value * mean / sd) %>%
      select(-mean, -sd) %>%
      group_by(variable) %>%
      mutate(key = 1, key = cumsum(key)) %>%
      pivot_wider(id_cols = c(key, group), names_from = variable, values_from = value) %>%
      select(-key)
    
       group       a        b        c
       <dbl>   <dbl>    <dbl>    <dbl>
     1     1 -0.0841  0.0384   0.0622 
     2     1  0.0247  0.00990  0.0529 
     3     1 -0.112  -0.0158   0.00505
     4     1  0.214  -0.0563  -0.135  
     5     1  0.0442  0.0286   0.0419 
     6     2 -0.166  -0.0445   0.0278 
     7     2  0.0984 -0.0160   0.0771 
     8     2  0.149   0.934    0.728  
     9     2  0.116   0.812    0.237  
    10     2 -0.0616  0.588   -0.207 
    

    【讨论】:

    • 谢谢!但我实际上希望将不同的数据帧视为彼此独立。本来可以更清楚
    • @sparklink 请问已经比较清楚是什么意思了?您是否需要来自df 的值以及来自df_summary 等数据的平均值和标准差,但这不是来自df 的数据?
    • 是的。因此将dfdf_summary 视为单独的数据帧。并将df 中的每个变量值乘以其对应的组“mean”并除以“sd”,实际上可以是任何数字。
    • @sparklink 我添加了上面的代码。请检查一下。
    【解决方案2】:

    另一种方法 - 使用矢量化和一些争论将矩阵恢复为 tibble 格式

    library(tidyverse)
    set.seed(1)
    df <- tibble(a = rnorm(10), b = rnorm(10), c = rnorm(10)) %>% mutate( group = c(rep(1, 5), rep(2, 5)), .before = "a")
    
    df %>%
      group_nest(group) %>%
      mutate(data = map(data, Vectorize(\(col) col * mean(col) / sd(col))),
             data = map(data, as_tibble)) %>%
      unnest(c(data))
    
    #> # A tibble: 10 x 4
    #>    group       a        b        c
    #>    <dbl>   <dbl>    <dbl>    <dbl>
    #>  1     1 -0.0843  0.0385   0.0622 
    #>  2     1  0.0247  0.00992  0.0529 
    #>  3     1 -0.112  -0.0158   0.00504
    #>  4     1  0.215  -0.0563  -0.135  
    #>  5     1  0.0443  0.0286   0.0419 
    #>  6     2 -0.166  -0.0444   0.0278 
    #>  7     2  0.0985 -0.0160   0.0771 
    #>  8     2  0.149   0.933    0.728  
    #>  9     2  0.116   0.812    0.237  
    #> 10     2 -0.0617  0.587   -0.207
    

    请注意,生成的 tibble 未分组

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多