R: Смешайте несколько столбцов и выберите значения строки из одного столбца на основе условия строки - PullRequest
0 голосов
/ 20 мая 2018

У меня есть фрейм данных с несколькими текстовыми столбцами.Мне нужно вывести только одно со значениями строки в зависимости от того, присутствует строка или нет.Поэтому, если мой ввод выглядит как:

Kingdom  | Phylum            | Class             | Order                |
-------------------------------------------------------------------------
Bacteria | Firmicutes        | Negativicutes     | Selenomonadales      |
Bacteria | Bact_unclassified | Bact_unclassified | Bact_unclassified    |
Bacteria | Firmicutes        | Negativicutes     | Negativ_unclassified |
Archaea  | Euryarchaeota     | Methanobacteria   | Methanobacteriales   |
Archaea  | Euryarchaeota     | Eury_unclassified | Eury_unclassified    |

Я хочу, чтобы мой вывод был таким:

Output               | 
-----------------------
o_Selenomonadales    |
k_Bacteria           | 
c_Negativicutes      |
o_Methanobacteriales |
p_Euryarchaeota      | 

Будучи префиксами в выходных строках: "k" из Kingldom, "p" изТип, «с» из класса и «о» из порядка.Обратите внимание, что ключевой строкой для фильтрации является «_unclassified».Есть идеи?

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Использование построчно apply предоставит возможность исследовать построчно данные.Найдите 1-ую колонку, которая содержит _unclassified.И вычтите 1, чтобы получить предыдущий столбец, который является желаемым столбцом для этой строки.

Теперь substring предоставляет возможность взять 1-й символ для нужного столбца, чтобы поставить перед ним префикс.

df$Output <- apply(df, 1, function(x){
      idx <- length(x)   #By default value from last column will be returned 
      if(length(which(grepl("_unclassified", x))) > 0 ){
        idx <- min(which(grepl("_unclassified", x)))-1
      } 
      paste(toupper(substring(names(df)[idx], 1, 1)), trimws(x[idx]), sep = "_")
       })

# Check result of 

df["Output"]
#                 Output
# 1    O_Selenomonadales
# 2           K_Bacteria
# 3      C_Negativicutes
# 4 O_Methanobacteriales
# 5      P_Euryarchaeota

Данные:

df <- read.table(text = 
  "Kingdom  | Phylum            | Class             | Order                
  Bacteria | Firmicutes        | Negativicutes     | Selenomonadales      
  Bacteria | Bact_unclassified | Bact_unclassified | Bact_unclassified    
  Bacteria | Firmicutes        | Negativicutes     | Negativ_unclassified 
  Archaea  | Euryarchaeota     | Methanobacteria   | Methanobacteriales   
  Archaea  | Euryarchaeota     | Eury_unclassified | Eury_unclassified",
  sep = "|", header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 20 мая 2018
library(tidyverse)

dat <- read_delim(
"Kingdom  | Phylum            | Class             | Order                
Bacteria | Firmicutes        | Negativicutes     | Selenomonadales      
Bacteria | Bact_unclassified | Bact_unclassified | Bact_unclassified    
Bacteria | Firmicutes        | Negativicutes     | Negativ_unclassified 
Archaea  | Euryarchaeota     | Methanobacteria   | Methanobacteriales   
Archaea  | Euryarchaeota     | Eury_unclassified | Eury_unclassified    
", delim = "|", trim_ws = TRUE)

priority = c(Order = 1L, Class = 2L, Phylum = 3L, Kingdom = 4L)

dat %>% 
  mutate(id = row_number()) %>% 
  gather(variable, value, -id) %>% 
  mutate(priority = priority[variable]) %>% 
  arrange(id, priority) %>% 
  group_by(id)  %>% 
  slice(detect_index(value, Negate(grepl), pattern = "unclassified$")) %>% 
  mutate(Output = paste(tolower(substr(variable, 1, 1)), value, sep = "_"))

# # A tibble: 5 x 5
# # Groups: id [5]
#      id variable value              priority Output              
#   <int> <chr>    <chr>                 <int> <chr>               
# 1     1 Order    Selenomonadales           1 o_Selenomonadales   
# 2     2 Kingdom  Bacteria                  4 k_Bacteria          
# 3     3 Class    Negativicutes             2 c_Negativicutes     
# 4     4 Order    Methanobacteriales        1 o_Methanobacteriales
# 5     5 Phylum   Euryarchaeota             3 p_Euryarchaeota 

Другой способ использования coalesce:

dat %>% 
  imap_dfc(~ paste(tolower(substr(.y, 1, 1)), .x, sep = "_")) %>% 
  mutate_all(function(x) ifelse(grepl("unclassified$", x), NA, x)) %>% 
  mutate(Output = coalesce(Order, Class, Phylum, Kingdom))

# # A tibble: 5 x 5
#   Kingdom    Phylum          Class             Order                Output              
#   <chr>      <chr>           <chr>             <chr>                <chr>               
# 1 k_Bacteria p_Firmicutes    c_Negativicutes   o_Selenomonadales    o_Selenomonadales   
# 2 k_Bacteria NA              NA                NA                   k_Bacteria          
# 3 k_Bacteria p_Firmicutes    c_Negativicutes   NA                   c_Negativicutes     
# 4 k_Archaea  p_Euryarchaeota c_Methanobacteria o_Methanobacteriales o_Methanobacteriales
# 5 k_Archaea  p_Euryarchaeota NA                NA                   p_Euryarchaeota
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...