This is a tricky one to describe concisely in a headline (or to google). I have a taxonomy table where some columns may be listed as "dropped' based on a confidence level. I'd like to replace any column that says "dropped" with "Unidentified" followed by the value from the first column that doesn't say "dropped", in a row-wise fashion. So, the input would look like this:
#> # A tibble: 21 x 4
#> domain class order species
#> <chr> <chr> <chr> <chr>
#> 1 Eukaryota dropped dropped dropped
#> 2 Eukaryota dropped dropped dropped
#> 3 Eukaryota dropped dropped dropped
#> 4 Eukaryota dropped dropped dropped
#> 5 Eukaryota dropped dropped dropped
#> 6 Eukaryota dropped dropped dropped
#> 7 Eukaryota Hexanauplia Calanoida dropped
#> 8 Eukaryota dropped dropped dropped
#> 9 Eukaryota Dinophyceae Syndiniales dropped
#> 10 Animals Polychaeta Terebellida dropped
#> 11 Eukaryota Acantharia Chaunacanthida dropped
#> 12 Eukaryota dropped dropped dropped
#> 13 Animals Ascidiacea Stolidobranchia dropped
#> 14 Eukaryota Haptophyta dropped dropped
#> 15 Eukaryota dropped dropped dropped
#> 16 Eukaryota dropped dropped dropped
#> 17 Eukaryota dropped dropped dropped
#> 18 Animals Ascidiacea Stolidobranchia dropped
#> 19 Eukaryota dropped dropped dropped
#> 20 Eukaryota dropped dropped dropped
And the output should look like this:
#> # A tibble: 21 x 4
#> domain class order species
#> <chr> <chr> <chr> <chr>
#> 1 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 2 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 3 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 4 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 5 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 6 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 7 Eukaryota Hexanauplia Calanoida Unidentified Calanoida
#> 8 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 9 Eukaryota Dinophyceae Syndiniales Unidentified Syndiniales
#> 10 Animals Polychaeta Terebellida Unidentified Terebellida
#> 11 Eukaryota Acantharia Chaunacanthida Unidentified Chaunacanth…
#> 12 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 13 Animals Ascidiacea Stolidobranchia Unidentified Stolidobran…
#> 14 Eukaryota Haptophyta Unidentified Haptop… Unidentified Haptophyta
#> 15 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 16 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 17 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 18 Animals Ascidiacea Stolidobranchia Unidentified Stolidobran…
#> 19 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 20 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
I've come up with a fine solution using purrr::pmap_dfr
but I'm curious to know if there's a more "pure" dplyr
way to do it? The one flaw in my method is that it doesn't work for columns where the first non-"dropped" column comes after one or more "dropped" columns (see row 21 in the output below). Here's my current solution:
library(tidyverse)
otu_table <- structure(list(domain = c("Eukaryota", "Eukaryota", "Eukaryota",
"Eukaryota", "Eukaryota", "Eukaryota", "Eukaryota", "Eukaryota",
"Eukaryota", "Animals", "Eukaryota", "Eukaryota", "Animals",
"Eukaryota", "Eukaryota", "Eukaryota", "Eukaryota", "Animals",
"Eukaryota", "Eukaryota", "dropped"), class = c("dropped", "dropped",
"dropped", "dropped", "dropped", "dropped", "Hexanauplia", "dropped",
"Dinophyceae", "Polychaeta", "Acantharia", "dropped", "Ascidiacea",
"Haptophyta", "dropped", "dropped", "dropped", "Ascidiacea",
"dropped", "dropped", "not dropped"), order = c("dropped", "dropped",
"dropped", "dropped", "dropped", "dropped", "Calanoida", "dropped",
"Syndiniales", "Terebellida", "Chaunacanthida", "dropped", "Stolidobranchia",
"dropped", "dropped", "dropped", "dropped", "Stolidobranchia",
"dropped", "dropped", "dropped"), species = c("dropped", "dropped",
"dropped", "dropped", "dropped", "dropped", "dropped", "dropped",
"dropped", "dropped", "dropped", "dropped", "dropped", "dropped",
"dropped", "dropped", "dropped", "dropped", "dropped", "dropped",
"dropped")), row.names = c(NA, -21L), class = c("tbl_df", "tbl",
"data.frame"))
tax_data <- otu_table %>%
pmap_dfr(~{
items <- list(...)
first_dropped = match("dropped",items)
if (first_dropped > 1) {
dropped_name <- str_c("Unidentified ",items[first_dropped-1])
} else {
dropped_name <- "Unidentified"
}
items[-c(1:first_dropped-1)] <- dropped_name
items
})
print(tax_data,n=30)
#> # A tibble: 21 x 4
#> domain class order species
#> <chr> <chr> <chr> <chr>
#> 1 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 2 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 3 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 4 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 5 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 6 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 7 Eukaryota Hexanauplia Calanoida Unidentified Calanoida
#> 8 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 9 Eukaryota Dinophyceae Syndiniales Unidentified Syndiniales
#> 10 Animals Polychaeta Terebellida Unidentified Terebellida
#> 11 Eukaryota Acantharia Chaunacanthida Unidentified Chaunacanth…
#> 12 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 13 Animals Ascidiacea Stolidobranchia Unidentified Stolidobran…
#> 14 Eukaryota Haptophyta Unidentified Haptop… Unidentified Haptophyta
#> 15 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 16 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 17 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 18 Animals Ascidiacea Stolidobranchia Unidentified Stolidobran…
#> 19 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 20 Eukaryota Unidentified Eukary… Unidentified Eukary… Unidentified Eukaryota
#> 21 dropped not dropped dropped dropped
Update:
Some good answers below. I've accepted the one with the most upvotes, but it turns out that after running all the suggestions through microbenchmark
, the purrr
solution is the fastest by almost an order of magnitude.