 <p>There might be a simpler way, but this combo of dplyr and tidyr works:</p> <pre><code>library(dplyr) library(tidyr) data3 &lt;- data1 %&gt;% group_by(tag) %&gt;% mutate(obstag = paste0("Obs", seq_along(Obs)), # Add markers eftag = paste0("Ef", seq_along(Effect)), altag = paste0("A", seq_along(Allele))) %&gt;% spread(altag, Allele) %&gt;% # Switch from rows to columns spread(obstag, Obs) %&gt;% spread(eftag, Effect) %&gt;% summarise_each(funs(unique(na.omit(.))), 1:Ef3) %&gt;% # Collapse into one row per tag mutate(Allele = paste(A1, A2, A3, sep = "/")) %&gt;% # paste alleles together select(-A1, -A2, -A3, -tag) # drop unwanted columns </code></pre>