从宽到长收集数据帧,并在R中使用tidyverse生成新列

时间:2019-11-24 18:41:45

标签: r tidyverse

我的数据如下:

df1<-read.table(text=" A	A1	B	B1	C	C1
12	7	11	4	16	9
12	6	13	8	12	7
14	6	14	2	11	5
13	5	14	3	10	6
11	4	15	6	9	4
10	3	16	7	`8	3
9	2	18	4	`12	12",header=TRUE)

我想得到以下结果。为了节省空间,我没有生成其余部分,因为我觉得没有必要

Group	Time	Value
M	A	12
N	A1	7
M	B	11
N	B1	4
M	C	16
N	C1	9
M	A	12
N	A1	6
M	B	13
N	B1	8
M	C	12
N	C1	7
M	A	14
N	A1	6
M	B	14
N	B1	2
M	C	11
N	C1	5
.	.	.
.	.	.
.	.	.
.	.	.

我所做的是:

df2<-gather(df1,Group, Time)

A,B,C被归类为M,而A1,B1和C1被归类为N。有人可以帮助吗?

3 个答案:

答案 0 :(得分:2)

您可以使用if_else创建另外一列:

library(dplyr)
library(tidyr)
group1 <- names(df1)[grepl(".+1$", names(df1))]
df <- tidyr::gather(df1, Time, Value) %>%
  dplyr::mutate(Group = if_else(Time %in% group1, "N", "M"))

之后,您可以按照自己的方式排列行和列。

输出

Time Value Group
1     A    12     M
2     A    12     M
3     A    14     M
4     A    13     M
5     A    11     M
6     A    10     M
7     A     9     M
8    A1     7     N
9    A1     6     N
10   A1     6     N
11   A1     5     N
12   A1     4     N
13   A1     3     N
14   A1     2     N
15    B    11     M
...

答案 1 :(得分:2)

如果要将Group设为N(如果以“ 1”结尾(其余M)),则可以执行以下操作:

library(tidyverse)

df1 %>%
  pivot_longer(cols = everything(), names_to = "Time", values_to = "Value") %>%
  mutate(Group = if_else(endsWith(Time, "1"), "N", "M"))

建议使用pivot_longer代替gather,并以最新的tidyr作为替代。

答案 2 :(得分:0)

尝试一下:

df1<-read.table(text=" A    A1  B   B1  C   C1
12  7   11  4   16  9
12  6   13  8   12  7
14  6   14  2   11  5
13  5   14  3   10  6
11  4   15  6   9   4
10  3   16  7   8   3
9   2   18  4   12  12",header=TRUE)

df2 = gather(df1)

df2$Group = ifelse(grepl('\\d', x = df2$key), 'N', 'M')

相应地更改列名。

结果:

> df2
   key value Group
1    A    12     M
2    A    12     M
3    A    14     M
4    A    13     M
5    A    11     M
6    A    10     M
7    A     9     M
8   A1     7     N
9   A1     6     N
10  A1     6     N
11  A1     5     N
12  A1     4     N
13  A1     3     N
...