R : Reshape Long => wide with different value length

36 Views Asked by At

I want to reshape from long to wide the following data base

df_long <- data.frame(
  indiv_id = c(rep(1,2), rep(2,6), rep(3,4)),
  value = c(sample(x = 2), sample(x = 6), sample(x = 4)),
  field_id = c("A", "B", "A", "C", "D", "E", "G", "F", "B", "D", "E", "F")
)


   indiv_id value field_id
1         1     1        A
2         1     2        B
3         2     6        A
4         2     1        C
5         2     5        D
6         2     4        E
7         2     2        G
8         2     3        F
9         3     4        B
10        3     1        D
11        3     2        E
12        3     3        F

And I want to turn this into wide format as follow (if possible with R base functions)

  indiv1_id  A  B  D  E  F
1         1  1  2 NA NA NA
2         2  6 NA  5  4  3
3         3 NA  4  1  2  3

I have looked at acast, spread etc ... but none of them made the job ! Thanks

2

There are 2 best solutions below

0
ThomasIsCoding On

reshape in base R

reshape(
  df_long,
  direction = "wide",
  idvar = "indiv_id",
  timevar = "field_id"
)

gives

  indiv_id value.A value.B value.C value.D value.E value.G value.F
1        1       1       2      NA      NA      NA      NA      NA
3        2       2      NA       5       4       1       6       3
9        3      NA       1      NA       2       4      NA       3
0
s_baldur On

There is always a solution if you go back to basics:

df_wide <- data.frame(id = unique(df_long$indiv_id))
df_wide[unique(df_long$field_id)] <- NA_real_
for (i in seq_len(nrow(df_long))) {
  with(df_long, df_wide[match(indiv_id[i], df_wide$id), field_id[i]] <<- value[i])
}

df_wide
#   id  A  B  C  D  E  G  F
# 1  1  2  1 NA NA NA NA NA
# 2  2  4 NA  5  2  1  6  3
# 3  3 NA  4 NA  1  3 NA  2

Reproducible data:

set.seed(43)
df_long <- data.frame(
  indiv_id = c(rep(1,2), rep(2,6), rep(3,4)),
  value = c(sample(x = 2), sample(x = 6), sample(x = 4)),
  field_id = c("A", "B", "A", "C", "D", "E", "G", "F", "B", "D", "E", "F")
)