My data looks like this:
ID Year
1 1990
2 1990
3 1991
4 1992
5 1995
I want to add six countries to each observation (let's say countries A, B, C, D, E, F). In total, I will have 30 observations. So I expect the data to be like this:
ID Year Country
1 1990 A
1 1990 B
1 1990 C
1 1990 D
1 1990 E
1 1990 F
2 1990 A
2 1990 B
2 1990 C
2 1990 D
2 1990 E
2 1990 F
3 1991 A
3 1991 B
3 1991 C
3 1991 D
3 1991 E
3 1991 F
4 1992 A
4 1992 B
4 1992 C
4 1992 D
4 1992 E
4 1992 F
5 1995 A
5 1995 B
5 1995 C
5 1995 D
5 1995 E
5 1995 F
CodePudding user response:
Base R:
countries <- LETTERS[1:6] # whatever you really have as a vector
out <- merge(dat, data.frame(Country = countries), by = NULL)
out[c(1:3, 28:30),]
# ID Year Country
# 1 1 1990 A
# 2 2 1990 A
# 3 3 1991 A
# 28 3 1991 F
# 29 4 1992 F
# 30 5 1995 F
Note that this works with data.frame
and tbl_df
, but data.table::merge
does not allow by=NULL
for cartesian expansion.
Data
dat <- structure(list(ID = 1:5, Year = c(1990L, 1990L, 1991L, 1992L, 1995L)), class = "data.frame", row.names = c(NA, -5L))
CodePudding user response:
We could use crossing
library(tidyr)
crossing(df1, Country = LETTERS[1:6])
-output
# A tibble: 30 × 3
ID Year Country
<int> <int> <chr>
1 1 1990 A
2 1 1990 B
3 1 1990 C
4 1 1990 D
5 1 1990 E
6 1 1990 F
7 2 1990 A
8 2 1990 B
9 2 1990 C
10 2 1990 D
# … with 20 more rows
Or using base R
with rep
out <- cbind(df1[rep(seq_len(nrow(df1)), each = 6),], Country = LETTERS[1:6])
data
df1 <- structure(list(ID = 1:5, Year = c(1990L, 1990L, 1991L, 1992L,
1995L)), class = "data.frame", row.names = c(NA, -5L))