[英]Gather multiple columns with gather in R
I would like to gather multiple columns of a dataframe in R to make it 'tidy'.我想在 R 中收集 dataframe 的多列以使其“整洁”。
library(tidyverse)
set.seed(123)
df <- data.frame(time = seq(1,5,1),
value_model_a = rnorm(5),
ci_low_model_a = rnorm(5),
ci_high_model_a = rnorm(5),
value_model_b = rnorm(5),
ci_low_model_b = rnorm(5),
ci_high_model_b = rnorm(5))
# time value_model_a ci_low_model_a ci_high_model_a value_model_b ci_low_model_b ci_high_model_b
#1 1 -0.3591146 -0.5881655 -0.4486189 0.7821898 -0.5315449 0.06015936
#2 2 0.8952444 -1.6314973 0.5618802 0.8228834 -0.2663575 -0.09029613
#3 3 -1.8961105 1.1529703 0.8896495 -0.1524523 0.5989563 0.35738994
#4 4 0.3471419 0.4373451 -0.7503646 0.3670275 1.7109441 0.11028077
#5 5 1.2780844 -1.3069509 -0.1286071 1.4340957 1.1876910 -1.69710214
Expected output预期 output
# time model value ci_low ci_high
# 1 a -0.3591146 -0.5881655 -0.4486189
# 2 a 0.8952444 ... and so on
Question问题
I am struggling to use the gather
function from the tidyr
package.我正在努力使用来自
tidyr
package 的gather
function。 How do I use it properly to reorganize this dataframe?如何正确使用它来重组这个 dataframe?
Pivoting can be tough in the beginning.一开始,旋转可能会很困难。
The new version of gather()
is pivot_longer()
.新版本的
gather()
是pivot_longer()
。
Here is how you can achieve your expected output.以下是实现预期 output 的方法。
First, you could just tell the function to pivot everything as default, using only the time as your identifier:首先,您可以将 function 告诉 pivot 一切默认情况下,仅使用时间作为您的标识符:
pivot_longer(df, -time) %>% head(5)
#> # A tibble: 30 x 3
#> time name value
#> <dbl> <chr> <dbl>
#> 1 1 value_model_a -0.560
#> 2 1 ci_low_model_a 1.72
#> 3 1 ci_high_model_a 1.22
#> 4 1 value_model_b 1.79
#> 5 1 ci_low_model_b -1.07
This is a start, but you can go further by setting a names separator.这是一个开始,但您可以通过设置名称分隔符进一步 go。 You could also use a regex using
names_pattern
.您还可以使用
names_pattern
使用正则表达式。
df_l = pivot_longer(df, -time, names_sep="_model_", names_to=c("name", "model"))
df_l
#> # A tibble: 30 x 4
#> time name model value
#> <dbl> <chr> <chr> <dbl>
#> 1 1 value a -0.560
#> 2 1 ci_low a 1.72
#> 3 1 ci_high a 1.22
#> 4 1 value b 1.79
#> 5 1 ci_low b -1.07
#> 6 1 ci_high b -1.69
#> 7 2 value a -0.230
#> 8 2 ci_low a 0.461
#> 9 2 ci_high a 0.360
#> 10 2 value b 0.498
#> # ... with 20 more rows
Finally, your expected output can be achieved by using pivot_wider()
with default values (which I explicitely wrote for academic purpose):最后,您期望的 output 可以通过使用具有默认值的
pivot_wider()
来实现(我明确地为学术目的编写了该值):
pivot_wider(df_l, names_from = "name", values_from = "value")
#> # A tibble: 10 x 5
#> time model value ci_low ci_high
#> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 1 a -0.560 1.72 1.22
#> 2 1 b 1.79 -1.07 -1.69
#> 3 2 a -0.230 0.461 0.360
#> 4 2 b 0.498 -0.218 0.838
#> 5 3 a 1.56 -1.27 0.401
#> 6 3 b -1.97 -1.03 0.153
#> 7 4 a 0.0705 -0.687 0.111
#> 8 4 b 0.701 -0.729 -1.14
#> 9 5 a 0.129 -0.446 -0.556
#> 10 5 b -0.473 -0.625 1.25
Created on 2021-03-03 by the reprex package (v1.0.0)由reprex package (v1.0.0) 于 2021 年 3 月 3 日创建
set.seed(123)
library(tidyverse)
df <- data.frame(time = seq(1,5,1),
value_model_a = rnorm(5),
ci_low_model_a = rnorm(5),
ci_high_model_a = rnorm(5),
value_model_b = rnorm(5),
ci_low_model_b = rnorm(5),
ci_high_model_b = rnorm(5))
pivot_longer(df, -time, names_sep = "_model_", names_to = c(".value", "model"))
#> # A tibble: 10 x 5
#> time model value ci_low ci_high
#> <dbl> <chr> <dbl> <dbl> <dbl>
#> 1 1 a -0.560 1.72 1.22
#> 2 1 b 1.79 -1.07 -1.69
#> 3 2 a -0.230 0.461 0.360
#> 4 2 b 0.498 -0.218 0.838
#> 5 3 a 1.56 -1.27 0.401
#> 6 3 b -1.97 -1.03 0.153
#> 7 4 a 0.0705 -0.687 0.111
#> 8 4 b 0.701 -0.729 -1.14
#> 9 5 a 0.129 -0.446 -0.556
#> 10 5 b -0.473 -0.625 1.25
Created on 2021-03-03 by the reprex package (v1.0.0)由reprex package (v1.0.0) 于 2021 年 3 月 3 日创建
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.