1

My question is very similar to this one but in my case, I want the values to be in different columns instead of being concatenated to one.

For example, using the following toy dataframe,

Input:

  Patient    Value
    1         'A' 

    1         'B'

    1         'C' 

    1         'D' 

    2         'B' 

    2        

    2         'E'

    and so on.....

I would like to create a new one where all the measurements are grouped per patient, i.e. Output:

  Patient    Value1    Value 2  Value 3  Value  
    1         'A'        'B'      'C'     'D'
    2         'B'                 'E'

Please note the absence of a value is still taken into account. How can I do that in R?

azal
  • 1,210
  • 6
  • 23
  • 43

1 Answers1

3

We could spread the data into 'wide' format after creating a sequence by 'Patient'

library(tidyverse)
df1 %>% 
     group_by(Patient) %>% 
     mutate(nm = str_c("Value", row_number())) %>%
     spread(nm, Value, fill = "")
# A tibble: 2 x 5
# Groups:   Patient [2]
#  Patient Value1 Value2 Value3 Value4
#    <int> <chr>  <chr>  <chr>  <chr> 
#1       1 A      B      C      D     
#2       2 B      ""     E      ""    

data

df1 <- structure(list(Patient = c(1L, 1L, 1L, 1L, 2L, 2L, 2L), Value = c("A", 
 "B", "C", "D", "B", NA, "E")), class = "data.frame", row.names = c(NA, 
 -7L))
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Thanks for the reply! It works like a charm. The only problem is that the newly created spread columns are re-arranged alphabetically or something. E.g Column Value10 will be after column Value1. Can we avoid that? – azal Apr 17 '19 at 19:08
  • @laza yes, after the mutate step, convert the 'nm' to `factor` with `levels` specified `%>% mutate(nm = factor(nm, levels = unique(nm))) %>% spread(nm, Value, fill = "")` – akrun Apr 18 '19 at 00:34