WedX - журнал о программировании и компьютерных науках

Суммирование значений столбца от S до следующего

У меня есть несколько фреймов данных, которые выглядят так (сокращенно):

ref       perc_fragments rank_code scientific_name 
Sample1   73.43          S         Escherichia coli                  
Sample1   2.10           S1        Escherichia coli P12b             
Sample1   1.40           S2        Escherichia coli CFT073           
Sample1   0.70           S1        Escherichia coli O6:H16
Sample1   1.40           S         Klebsiella pneumoniae     
Sample1   0.70           S         Shigella dysenteriae      
Sample1   1.40           S         Staphylococcus aureus     
Sample1   1.40           S1        S. aureus xyz

Что я хочу сделать, так это суммировать perc_fragments для всех строк в одной группе. Первый S в столбце rank_code начинает группу, и все S1 или S2 после этого являются частью этой группы, пока не встретится новый S. В приведенном выше случае первые четыре строки представляют собой одну группу, затем идут три строки с однорядными группами, а последние две строки представляют собой одну группу. Я хочу, чтобы в столбце научное_имя отображалось научное_имя строки S для каждой группы с суммой S и всех S1 в одной группе. Другими словами, это:

ref       perc_fragments rank_code scientific_name 
Sample1   77.63          S         Escherichia coli                  
Sample1   1.40           S         Klebsiella pneumoniae     
Sample1   0.70           S         Shigella dysenteriae      
Sample1   2.8            S         Staphylococcus aureus

Я пробовал несколько вещей, но простой grepl не сработает, чтобы сгруппировать их вместе, так как scientific_name может немного отличаться для S1 строк.

Тестовые данные:

structure(list(ref = c("Sample1", "Sample1", "Sample1", "Sample1", 
"Sample1", "Sample1", "Sample1", "Sample1", "Sample1", "Sample1", 
"Sample1", "Sample1", "Sample1", "Sample1", "Sample1", "Sample1", 
"Sample1", "Sample1", "Sample1", "Sample1", "Sample1"), perc_fragments = c("73.43", 
"2.10", "1.40", "0.70", "1.40", "0.70", "0.70", "0.70", "0.70", 
"0.70", "0.70", "0.70", "0.70", "0.70", "0.70", "1.40", "0.70", 
"0.70", "0.70", "1.40", "1.40"), rank_code = c("S", "S1", "S1", 
"S2", "S1", "S1", "S1", "S1", "S1", "S2", "S1", "S1", "S1", "S1", 
"S1", "S", "S", "S", "S", "S", "S1"), scientific_name = c("Escherichia coli", 
"Escherichia coli P12b", "Escherichia coli O157:H7", "Escherichia coli O157:H7 str. SS17", 
"Escherichia coli CFT073", "Escherichia coli O6:H16", "Escherichia coli APEC IMT5155", 
"Escherichia coli UM146", "Escherichia coli C", "Escherichia coli ATCC 8739", 
"Escherichia coli FAP1", "Escherichia coli O27:H7", "Escherichia coli IAI1", 
"Escherichia coli O127:H6", "Escherichia coli PCN061", "Klebsiella pneumoniae", 
"Klebsiella variicola", "Citrobacter freundii", "Shigella dysenteriae", 
"Staphylococcus aureus", "Staphylococci haemolyticus"
)), row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame"
))
r
10.03.2021

Ответы:


1

Это работает:

library(dplyr)
df %>% mutate(grp = cumsum(rank_code == 'S')) %>% group_by(grp) %>% 
  mutate(perc_fragments = sum(perc_fragments)) %>% 
   filter(rank_code == 'S') %>% ungroup() %>% select(-grp)
# A tibble: 6 x 4
  ref     perc_fragments rank_code scientific_name      
  <chr>            <dbl> <chr>     <chr>                
1 Sample1           86.0 S         Escherichia coli     
2 Sample1            1.4 S         Klebsiella pneumoniae
3 Sample1            0.7 S         Klebsiella variicola 
4 Sample1            0.7 S         Citrobacter freundii 
5 Sample1            0.7 S         Shigella dysenteriae 
6 Sample1            2.8 S         Staphylococcus aureus
10.03.2021
  • Это было прекрасно, спасибо, что сообщили о cumsum! 10.03.2021

  • 2

    Используйте cumsum для создания новых групп всякий раз, когда 'S' встречается в столбце rank_code и sum значения perc_fragments в каждой группе.

    library(dplyr)
    
    df %>%
      group_by(ref, grp = cumsum(rank_code == 'S')) %>%
      summarise(perc_fragments = sum(as.numeric(perc_fragments)), 
                across(c(rank_code, scientific_name), first)) %>%
      ungroup() %>%
      select(-grp)
    
    #   ref     perc_fragments rank_code scientific_name      
    #  <chr>            <dbl> <chr>     <chr>                
    #1 Sample1           86.0 S         Escherichia coli     
    #2 Sample1            1.4 S         Klebsiella pneumoniae
    #3 Sample1            0.7 S         Klebsiella variicola 
    #4 Sample1            0.7 S         Citrobacter freundii 
    #5 Sample1            0.7 S         Shigella dysenteriae 
    #6 Sample1            2.8 S         Staphylococcus aureus
    
    10.03.2021

    3

    Вы можете использовать от cumsum(x$rank_code == "S") до split в разыскиваемых группах.

    do.call(rbind, lapply(split(x, cumsum(x$rank_code == "S")), function(y) {
      z <- y[1,]
      z$perc_fragments <- sum(y$perc_fragments)
      z
    }))
    #      ref perc_fragments rank_code       scientific_name
    #1 Sample1          77.63         S      Escherichia coli
    #2 Sample1           1.40         S Klebsiella pneumoniae
    #3 Sample1           0.70         S  Shigella dysenteriae
    #4 Sample1           2.80         S Staphylococcus aureus
    

    Данные:

    x <- read.table(header=TRUE, text="ref       perc_fragments rank_code scientific_name 
    Sample1   73.43          S         'Escherichia coli'
    Sample1   2.10           S1        'Escherichia coli P12b'
    Sample1   1.40           S2        'Escherichia coli CFT073'
    Sample1   0.70           S1        'Escherichia coli O6:H16'
    Sample1   1.40           S         'Klebsiella pneumoniae'
    Sample1   0.70           S         'Shigella dysenteriae'
    Sample1   1.40           S         'Staphylococcus aureus'
    Sample1   1.40           S1        'S. aureus xyz'")
    
    10.03.2021
    Новые материалы

    Как создать диаграмму градиентной кисти с помощью D3.js
    Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

    Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
    Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

    Лицензии с открытым исходным кодом: руководство для разработчиков и создателей
    В динамичном мире разработки программного обеспечения открытый исходный код стал мощной парадигмой, способствующей сотрудничеству, инновациям и прогрессу, движимому сообществом. В основе..

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


    Для любых предложений по сайту: [email protected]