【问题标题】:Data Frame to matrix - many rows数据框到矩阵 - 多行
【发布时间】:2020-01-15 22:58:18
【问题描述】:

我正在尝试将 data.frame 转换为矩阵。我计算了 iris 数据集的一些统计数据,并希望将每个统计数据放在单独的行中。下面的代码在一行中显示了所有统计数据(平均值和中位数),这不是所需的输出。我想要这样的东西:

stat Sepal.Lenght  Sepal.Width  ....
avg     10.5          .....
med    ......         .....

代码如下:

data_iris <- iris
avg <- data_iris %>%
  summarise_at(vars(Sepal.Length:Petal.Width),mean,na.rm=TRUE)

med <- data_iris %>%
  summarise_at(vars(Sepal.Length:Petal.Width),median,na.rm=TRUE)


column <- colnames(data_iris[1:4])
rown <- c("avg","median")

df <- data.frame(avg=avg,med=med)
m <- data.matrix(df)

还有一个问题:我想计算分位数,但出现错误:

qrtl <- data_iris %>%
  summarise_at(vars(Sepal.Length:Petal.Width),quantile,na.rm=TRUE)

错误:列 Sepal.Length 的长度必须为 1(汇总值),而不是 5

怎么了?

【问题讨论】:

  • 为了好玩,Base R 替代品,它提供了 matrix 输出 - sapply(data_iris[1:4], function(x) c(mean=mean(x),median=median(x)))

标签: r


【解决方案1】:

如果我们使用pivot_longer 将其重塑为“长”,就可以做到

library(dplyr)
library(tidyr)
iris %>% 
   summarise_if(is.numeric, list(avg = mean, med = median)) %>% 
   pivot_longer(everything(), names_to = c('.value', 'stat'), names_sep="_")
#    stat Sepal.Length Sepal.Width Petal.Length Petal.Width
#1  avg     5.843333    3.057333        3.758    1.199333
#2  med     5.800000    3.000000        4.350    1.300000

如果需要转换为matrix,则将'stat'改为rownames,然后使用data.matrix

library(tibble)
iris %>% 
   summarise_if(is.numeric, list(avg = mean, med = median)) %>% 
   pivot_longer(everything(), names_to = c('.value', 'stat'), names_sep="_") %>% 
   column_to_rownames('stat') %>%
   data.matrix

quantiledev 版本的dplyr 中运行良好 - 0.8.99.9000`

iris %>%        
    summarise_at(vars(Sepal.Length:Petal.Width),quantile, na.rm=TRUE)
#  Sepal.Length Sepal.Width Petal.Length Petal.Width
#1          4.3         2.0         1.00         0.1
#2          5.1         2.8         1.60         0.3
#3          5.8         3.0         4.35         1.3
#4          6.4         3.3         5.10         1.8
#5          7.9         4.4         6.90         2.5

OP 的包版本是0.8.3,所以可能用list 包装会起作用

iris %>%
   summarise_at(vars(Sepal.Length:Petal.Width),
         list(quantile = ~ list(quantile(., na.rm=TRUE)))) %>% 
   unnest(c(names(.)))

【讨论】:

  • 谢谢。对于分位数,我使用相同的(我什至从你的帖子中复制了它)代码,这就是我得到的:+ summarise_at(vars(Sepal.Length:Petal.Width),quantile, na.rm=TRUE) ERROR: Column Sepal.Length` 必须是长度 1(汇总值),而不是 5`
  • @Muska 你能显示你的dplyrpackageVersion('dplyr')。我认为它必须与版本有关
  • 是的,当前版本是 0.8.3
  • @Muska 我使用的是开发版‘0.8.99.9000’,但在您的情况下,如果我们将其包装在list 中,则可以纠正它
  • @Muska 你能试试iris %&gt;% summarise_at(vars(Sepal.Length:Petal.Width),list(quantile = ~ list(quantile(., na.rm=TRUE)))) %&gt;% unnest(c(names(.)))
【解决方案2】:

我们可以将maptranspose 一起使用,然后将来自不同统计信息的行绑定在一起。

library(purrr)

map(data_iris[1:4], ~list(mean = mean(.x), sd = sd(.x))) %>%
  transpose() %>%
  dplyr::bind_rows(.id = "statistics")

# A tibble: 2 x 5
#  statistics Sepal.Length Sepal.Width Petal.Length Petal.Width
#  <chr>             <dbl>       <dbl>        <dbl>       <dbl>
#1 mean              5.84        3.06          3.76       1.20 
#2 sd                0.828       0.436         1.77       0.762

或者

map_df(data_iris[1:4], ~c(mean = mean(.x), sd = sd(.x))) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-05-10
    • 2016-02-14
    • 2017-11-01
    相关资源
    最近更新 更多