【问题标题】:How to Transpose (t) in the Tidyverse Using Tidyr如何使用 Tidyr 在 Tidyverse 中转置 (t)
【发布时间】:2018-04-17 23:33:33
【问题描述】:

使用示例数据(底部),我想使用下面的代码对数据进行分组和汇总。在此之后,我想转置,但我被困在如何使用 tidyr 来实现这一点?

对于上下文,我正在尝试重新创建一个使用 knitr::kable 在 Excel 中创建的现有表,因此我的以下代码的最终产品预计会打破整洁的原则。

例如:

library(tidyverse)

Df <- Df %>% group_by(Code1, Code2, Level) %>%
    summarise_all(funs(count = sum(!is.na(.))))

我可以使用管道添加 t(.)...

Df <- Df %>% group_by(Code1, Code2, Level) %>%
    summarise_all(funs(count = sum(!is.na(.)))) %>%
    t(.)

或者我可以添加...

Df <- as.data.frame(t(Df)

这两个选项都允许我进行转置,但我想知道是否有使用 tidyr 的 gatherspread 函数实现此目的的 tidyverse 方法?我想对进程有更多的控制权,并且还想删除在使用转置时显示为列名的“V1”、“V2”等 (t)。

如何使用 tidyverse 实现这一目标?

示例代码:

Code1 <- c("H200","H350","H250","T400","T240","T600")
Code2 <- c("4A","4A","4A","2B","2B","2B")
Level <- c(1,2,3,1,2,3)
Q1 <- c(30,40,40,50,60,80)
Q2 <- c(50,30,50,40,80,30)
Q3 <- c(30,45,70,42,81,34)

Df <- data.frame(Code1, Code2, Level, Q1, Q2, Q3)

【问题讨论】:

  • 这是个坏主意,因为它搞砸了所有变量类型。 tidyverse 是整洁的,因为它是由 to keep data tidy 构建的,即在列中包含变量,在行中包含观察值。打破这个成语是完全可能的,但大多数时候它只会让你的生活变得悲惨,比如像你在这里所做的那样把所有东西都变成一个字符矩阵(主要是数字)。
  • 我打破整洁原则的原因是因为决赛桌是为了展示。我正在尝试重新创建现有的 Excel 文档。我打算在最终输出中使用 knitr::kable,这就是我的问题的背景。

标签: r dplyr tidyr tidyverse


【解决方案1】:

tidyverse 中的通用习语是将您的数据gather() 最大化,形成一个“长”数据框,每行一个测量值。然后,spread() 可以将此长数据帧恢复为您最喜欢的任何“宽”格式。这个过程可以有效地转置数据:只需gather()所有标识符列除了行名,然后spread()行名。

例如,这里是如何有效地转置mtcars

require(tidyverse)

mtcars %>% 
    rownames_to_column %>%
    gather(variable, value, -rowname) %>% 
    spread(rowname, value)

您的数据没有 R 中所理解的“行名称”,但 Code1 有效地用作行名称,因为它唯一标识数据的每一(原始)行。

Df1 <- Df %>% 
    group_by(Code1, Code2, Level) %>%
    summarise_all(funs(count = sum(!is.na(.)))) %>%
    gather(column, value, -Code1) %>%
    spread(Code1, value)

tidyr 1.0 或更高版本的更新(2019 年末起)

新的pivot_wider()pivot_longer() 函数现在比旧的(但仍受支持)gather()spread() 更受欢迎。因此,转置 mtcars 的首选方法可能是

require(tidyverse)

mtcars %>% 
    rownames_to_column() %>%
    pivot_longer(-rowname, 'variable', 'value') %>%
    pivot_wider(variable, rowname)

【讨论】:

  • 如果您的 data.frame 或 tibble 具有不同的数据类型,您可能必须首先明确地将它们强制转换为一致的数据类型,例如使用应用(mtcars,2,as.character)。否则,pivot_longer 可能会导致错误。 (适用于 mtcar,但一般情况下可能不行)。
【解决方案2】:
library(tidyr)
library(dplyr)

Df <- Df %>% group_by(Code1, Code2, Level) %>%
    summarise_all(funs(count = sum(!is.na(.)))) %>%
    gather(var, val, 2:ncol(Df)) %>%
    spread(Code1, val)

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
猜你喜欢
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 2023-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多