【问题标题】:Calculate mean and sd for given variables in a dataframe计算数据框中给定变量的均值和标准差
【发布时间】:2022-01-23 06:29:28
【问题描述】:

给定数据框中数值变量名称的向量,我需要计算每个变量的均值和标准差。例如,给定 mtcars 数据集和以下变量名向量:

vars_to_transform <- c("mpg", "disp")

我希望得到以下结果:

我想到的第一个解决方案如下:

library(dplyr)
library(purrr)

data("mtcars")

vars_to_transform <- c("mpg", "disp")

vars_to_transform %>% 
  map_dfr( function(x) { c(variable = x, avg = mean(mtcars[[x]], na.rm = T), sd = sd(mtcars[[x]], na.rm = T)) } )

结果如下:

如您所见,所有返回的变量都是字符,但我希望有avgsd 的数字。

有没有办法解决这个问题?还是有比这更好的解决方案?

附: 我正在使用purr 0.3.4

【问题讨论】:

标签: r purrr


【解决方案1】:

以下工作(不要在代码中使用c(),而是使用tibble):

vars_to_transform %>% 
  map_dfr(~ tibble(variable = .x, avg = mean(mtcars[[.x]], na.rm = T), 
          sd = sd(mtcars[[.x]], na.rm = T))) 

解释: 对于c(),您使用的是一个向量,其元素必须具有相同的类型(在您的情况下为character,因为variablecharacter)。使用tibble,每个元素可以有不同的类型。

@Gwang-Jin Kim 建议,在我感谢的下面的评论中,人们也可以使用 list 而不是 tibble


或者尝试添加type.convert:

library(dplyr)
library(purrr)

data("mtcars")

vars_to_transform <- c("mpg", "disp")

vars_to_transform %>% 
  map_dfr( function(x) { c(variable = x, avg = mean(mtcars[[x]], na.rm = T), sd = sd(mtcars[[x]], na.rm = T)) } ) %>% 
  type.convert(as.is=T)

#> # A tibble: 2 × 3
#>   variable   avg     sd
#>   <chr>    <dbl>  <dbl>
#> 1 mpg       20.1   6.03
#> 2 disp     231.  124.

【讨论】:

  • 我不知道type.convert。很高兴知道!但我仍然想知道为什么即使每一行的 avg 和 sd 都被正确地计算为数字,为什么所有都被转换为字符。
  • @lucazav:查看我编辑的答案。
  • tibble 的插入使用 list 就足够了。
  • @PaulSmith 欢迎您!我的想法是——因为 R 中所有类似数据框的对象都有底层列表(向量列表——构成每一列的每个向量)——所以我猜想,list 也可以工作——确实如此。
  • @Gwang-Jin Kim:我刚刚编辑了我的答案,添加了您使用list 而不是tibble 的想法。
【解决方案2】:

select->pivot->group->summarise 的处理方式似乎过于复杂。

mtcars %>% 
    select(all_of(vars_to_transform)) %>%
    pivot_longer(everything()) %>% 
    group_by(name) %>% 
    summarise(
        mean = mean(value),
        sd = sd(value)
    )
# A tibble: 2 x 3
  name   mean     sd
  <chr> <dbl>  <dbl>
1 disp  231.  124.  
2 mpg    20.1   6.03

【讨论】:

  • 不错的一个!有时最简单的方法是隐藏在你的眼睛之外。谢谢!
【解决方案3】:

另一种选择:

library(purrr)
library(dplyr)

vars_to_transform <- c("mpg", "disp")
funs <- lst(mean, sd)

mtcars %>%
  select(all_of(vars_to_transform)) %>%
  map_df(~ funs %>%
           map(exec, .x), .id = "var")

# A tibble: 2 x 3
  var    mean     sd
  <chr> <dbl>  <dbl>
1 mpg    20.1   6.03
2 disp  231.  124.  

【讨论】:

  • 有趣的解决方案。谢谢!
【解决方案4】:
m <- mtcars[, vars_to_transform]
tibble(variable = names(m), avg = apply(m, 2, mean), sd = apply(m, 2, sd))

## A tibble: 2 × 3
#  variable   avg     sd
#  <chr>    <dbl>  <dbl>
#1 mpg       20.1   6.03
#2 disp     231.  124.  

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 2021-10-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 2018-06-08
    • 2014-03-21
    相关资源
    最近更新 更多