AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 77699767
Accepted
Kenn
Kenn
Asked: 2023-12-22 02:06:33 +0800 CST2023-12-22 02:06:33 +0800 CST 2023-12-22 02:06:33 +0800 CST

Divida o dataframe em vários dataframes agrupando colunas

  • 772

Eu tenho um dataframe de dados de expressão onde os genes são linhas e as colunas são amostras. Também tenho um dataframe contendo metadados para cada amostra no dataframe da expressão. Na realidade, meu dataframe expr tem mais de 30.000 linhas e mais de 100 colunas. No entanto, abaixo está um exemplo com dados menores.

expr <- data.frame(sample1 = c(1,2,2,0,0), 
                   sample2 = c(5,2,4,4,0), 
                   sample3 = c(1,2,1,0,1), 
                   sample4 = c(6,5,6,6,7), 
                   sample5 = c(0,0,0,1,1))
rownames(expr) <- paste0("gene",1:5)
meta <- data.frame(sample = paste0("sample",1:5),
                   treatment = c("control","control",
                                 "treatment1", 
                                 "treatment2", "treatment2"))

Quero encontrar a média de cada gene por tratamento. Dos exemplos que vi com split() ou group_by() agrupar pessoas com base em uma coluna já presente no data.frame. No entanto, tenho um dataframe separado (meta) que classifica o agrupamento das colunas em outro dataframe (expr).

Gostaria que minha saída fosse um dataframe com genes como linhas, tratamento como colunas e valores como média.

#        control   treatment1   treatment2
#  gene1  mean        mean         mean
#  gene2  mean        mean         mean
  • 5 5 respostas
  • 91 Views

5 respostas

  • Voted
  1. Friede
    2023-12-22T02:45:11+08:002023-12-22T02:45:11+08:00

    Uma abordagem na base R que funciona para o exemplo específico de dados de brinquedos fornecido:

    colnames(expr) = paste0(colnames(expr), "_", 
                            meta$treatment[match(colnames(expr), meta$sample)])
    vapply(unique(meta$treatment), 
           \(i) rowMeans(expr[grepl(i, colnames(expr))]), numeric(nrow(expr)))
    #>       control treatment1 treatment2
    #> gene1       3          1        3.0
    #> gene2       2          2        2.5
    #> gene3       3          1        3.0
    #> gene4       2          0        3.5
    #> gene5       0          1        4.0
    

    Dados

    expr <- data.frame(sample1 = c(1,2,2,0,0), 
                       sample2 = c(5,2,4,4,0), 
                       sample3 = c(1,2,1,0,1), 
                       sample4 = c(6,5,6,6,7), 
                       sample5 = c(0,0,0,1,1))
    rownames(expr) <- paste0("gene",1:5)
    
    meta <- data.frame(sample = paste0("sample",1:5),
                       treatment = c("control","control",
                                     "treatment1", 
                                     "treatment2", "treatment2"))
    
    • 3
  2. Best Answer
    Gregor Thomas
    2023-12-22T02:17:03+08:002023-12-22T02:17:03+08:00

    Algo assim. Não está totalmente claro o que você deseja agrupar na última etapa, mas você pode ajustar isso facilmente.

    library(dplyr)
    library(tidyr)
    
    expr |>
      mutate(gene = row.names(expr)) |>
      pivot_longer(-gene, names_to = "sample") |>
      left_join(meta, by = "sample") |>
      summarize(mean = mean(value), .by = c(gene, treatment)) |> 
      pivot_wider(names_from = treatment, values_from = mean)
    # # A tibble: 5 × 4
    #   gene  control treatment1 treatment2
    #   <chr>   <dbl>      <dbl>      <dbl>
    # 1 gene1       3          1        3  
    # 2 gene2       2          2        2.5
    # 3 gene3       3          1        3  
    # 4 gene4       2          0        3.5
    # 5 gene5       0          1        4  
    
    • 2
  3. 2023-12-22T03:34:56+08:002023-12-22T03:34:56+08:00

    Uma abordagem base R:

    expr|>
        split.default(with(meta, treatment[match(names(expr), sample)]))|>
        lapply(rowMeans)|>
        structure(dim=3)|>
        array2DF()
    
            Var1 gene1 gene2 gene3 gene4 gene5
    1    control     3   2.0     3   2.0     0
    2 treatment1     1   2.0     1   0.0     1
    3 treatment2     3   2.5     3   3.5     4
    
    • 2
  4. TarJae
    2023-12-22T03:16:12+08:002023-12-22T03:16:12+08:00

    Aqui está uma data.tableabordagem com a mesma lógica fornecida por @Gregor Thomas:

    library(data.table)
    
    expr_dt <- setDT(expr)
    expr_dt[, gene := rownames(expr)]
    
    meta_dt <- setDT(meta)
    
    melt(expr_dt, id.vars = "gene", variable.name = "sample", value.name = "expression")[
      meta_dt, on = .(sample)][
        , .(mean = mean(expression)), by = .(gene, treatment)][
          , dcast(.SD, gene ~ treatment, value.var = "mean")]
    
       gene control treatment1 treatment2
    1:    1       3          1        3.0
    2:    2       2          2        2.5
    3:    3       3          1        3.0
    4:    4       2          0        3.5
    5:    5       0          1        4.0
    
    • 1
  5. M--
    2023-12-22T04:08:10+08:002023-12-22T04:08:10+08:00

    Aqui está outra abordagem tidyverse, substituindo números de amostra por tratamentos, metacriando um vetor nomeado em vez de left_join()e também usando values_fninside pivot_wider()em vez de summarise():

    library(dplyr)
    library(tidyr)
    
    expr %>% 
      tibble::rownames_to_column("gene") %>% 
      pivot_longer(-gene) %>% 
      mutate(name = split(meta$treatment, meta$sample)[name]) %>%  %>% 
      pivot_wider(values_fn = mean)
    
    #> # A tibble: 5 × 4
    #>   gene  control treatment1 treatment2
    #>   <chr>   <dbl>      <dbl>      <dbl>
    #> 1 gene1       3          1        3  
    #> 2 gene2       2          2        2.5
    #> 3 gene3       3          1        3  
    #> 4 gene4       2          0        3.5
    #> 5 gene5       0          1        4
    

    Criado em 21/12/2023 com reprex v2.0.2

    • 0

relate perguntas

  • Adicionar número de série para atividade de cópia ao blob

  • A fonte dinâmica do empacotador duplica artefatos

  • Selecione linhas por grupo com 1s consecutivos

  • Lista de chamada de API de gráfico subscritoSkus estados Privilégios insuficientes enquanto os privilégios são concedidos

  • Função para criar DFs separados com base no valor da coluna

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    destaque o código em HTML usando <font color="#xxx">

    • 2 respostas
  • Marko Smith

    Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}?

    • 1 respostas
  • Marko Smith

    Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)?

    • 2 respostas
  • Marko Smith

    Por que as compreensões de lista criam uma função internamente?

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 respostas
  • Marko Smith

    Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)?

    • 4 respostas
  • Marko Smith

    Por que o construtor de uma variável global não é chamado em uma biblioteca?

    • 1 respostas
  • Marko Smith

    Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto?

    • 1 respostas
  • Marko Smith

    Somente operações bit a bit para std::byte em C++ 17?

    • 1 respostas
  • Martin Hope
    fbrereto Por que a resolução de sobrecarga prefere std::nullptr_t a uma classe ao passar {}? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 Você pode usar uma lista de inicialização com chaves como argumento de modelo (padrão)? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi Por que as compreensões de lista criam uma função internamente? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A formato fmt %H:%M:%S sem decimais 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python std::views::filter do C++20 não filtrando a visualização corretamente 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute Por que 'char -> int' é promoção, mas 'char -> short' é conversão (mas não promoção)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa Por que o construtor de uma variável global não é chamado em uma biblioteca? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis Comportamento inconsistente de std::common_reference_with em tuplas. Qual é correto? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev Por que os compiladores perdem a vetorização aqui? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan Somente operações bit a bit para std::byte em C++ 17? 2023-08-17 17:13:58 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve