Reputation: 431
I am relatively new to R and I am struggling with the following problem: I have a data frame that consists of two sets of x and y variables i.e. x1, y1 and x2, y2. I would like to use gather or any other function that could help to create a new data frame with merged x1 and x2 variables into a single x variable. I have tried to use gather but can see only examples applied to data frames with a single x variable. Bellow is my reprex with the desired output as well.
Your help is really appreciated. Thank you!
library(tidyr)
(df <- data.frame(x1=c(1,2,3),y1=c(10,14,12), x2=c(2,3,4),y2=c(12,13,11)))
#> x1 y1 x2 y2
#> 1 1 10 2 12
#> 2 2 14 3 13
#> 3 3 12 4 11
(df_tall <- gather(df,"z", "y", y1:y2))
#> x1 z y
#> 1 1 y1 10
#> 2 2 y1 14
#> 3 3 y1 12
#> 4 1 x2 2
#> 5 2 x2 3
#> 6 3 x2 4
#> 7 1 y2 12
#> 8 2 y2 13
#> 9 3 y2 11
# desired output
print('Desired output')
#> [1] "Desired output"
(df_mod <- data.frame(x=c(1,2,2,3,3,4),y=c(10,14,12,12,13,11), z=c("y1", "y1", "y2", "y1", "y2", "y2")))
#> x y z
#> 1 1 10 y1
#> 2 2 14 y1
#> 3 2 12 y2
#> 4 3 12 y1
#> 5 3 13 y2
#> 6 4 11 y2
Created on 2020-04-03 by the reprex package (v0.2.1)
Upvotes: 4
Views: 237
Reputation: 887981
We can use data.table
methods
library(data.table)
melt(setDT(df), measure = patterns('^x', '^y'),
variable.name = 'z', value.name = c('x', 'y'))
# z x y
#1: 1 1 10
#2: 1 2 14
#3: 1 3 12
#4: 2 2 12
#5: 2 3 13
#6: 2 4 11
Upvotes: 1
Reputation: 389335
gather
has been replaced with pivot_longer
in tidyr
which allows this.
tidyr::pivot_longer(df, cols = everything(),
names_to = c('.value', 'z'),
names_pattern = '(.)(.)')
# z x y
# <chr> <dbl> <dbl>
#1 1 1 10
#2 2 2 12
#3 1 2 14
#4 2 3 13
#5 1 3 12
#6 2 4 11
.value
is used when we want part of column name as a data in separate column. In names_pattern
we use regex to specify groups in which columns are divided. In this case, we use each character as separate group, hence the pattern. ((.)(.)
).
Upvotes: 3
Reputation: 19541
Can use reshape
here:
reshape(df, direction="long", varying=1:4, sep="", timevar="z")
z x y id
1.1 1 1 10 1
2.1 1 2 14 2
3.1 1 3 12 3
1.2 2 2 12 1
2.2 2 3 13 2
3.2 2 4 11 3
Upvotes: 2