вычислить z-оценку для нескольких фреймов данных в R - PullRequest
3 голосов
/ 06 августа 2020

У меня десять фреймов данных с одинаковым количеством строк и столбцов. Они выглядят так:

df1 <- data.frame(geneID=c("AKT1","AKT2","AKT3","ALK",
                           "APC"),
                  CDKN2A=c(3490,9447,4368,908,204),
                  INPP4B=c(NA,9459,4395,1030,NA),
                  BCL2=c(NA,9480,4441,1209,NA),
                  IRS2=c(NA,NA,4639,1807,NA),
                  HRAS=c(3887,9600,4691,1936,1723))

df2 <- data.frame(geneID=c("AKT1","AKT2","AKT3","ALK",
                           "APC"),
                  CDKN2A=c(10892,17829,7156,1325,387),
                  INPP4B=c(NA,17840,7185,1474,NA),
                  BCL2=c(NA,17845,7196,1526,NA),
                  IRS2=c(NA,NA,12426,10244,NA),
                  HRAS=c(11152,17988,7545,2734,2423))

df3 <- data.frame(geneID=c("AKT1","AKT2","AKT3","ALK",
                           "APC"),
                  CDKN2A=c(11376,17103,8580,780,178),
                  INPP4B=c(NA,17318,9001,2829,NA),
                  BCL2=c(NA,17124,8621,1141,NA),
                  IRS2=c(NA,NA,8658,1397,NA),
                  HRAS=c(11454,17155,8683,1545,1345))

Я хотел бы рассчитать z-оценку для каждого фрейма данных на основе среднего значения и дисперсии по нескольким фреймам данных. Z-оценка должна быть рассчитана следующим образом: z-оценка = (x-среднее (x)) / sd (x))).

Я обнаружил, что функция ddply для plyr может выполнять эту работу, но решение было для одного фрейма данных, в то время как у меня есть несколько фреймов данных в виде отдельных файлов с 18214 строками и 269 столбцами.

Буду признателен за любые предложения.

Большое спасибо за вашу помощь! Ольга

Ответы [ 2 ]

2 голосов
/ 06 августа 2020

Вот один из вариантов, в котором мы связываем наборы данных вместе с bind_rows (из dplyr), затем группируем по столбцу группировки и возвращаем zscore преобразованные числа c столбцы

library(dplyr)
bind_rows(df1, df2, df3, .id = 'grp') %>% 
     group_by(geneID) %>% 
     mutate(across(where(is.numeric), 
      ~(.- mean(., na.rm = TRUE))/sd(., na.rm = TRUE), .names = '{col}_zscore'))

ПРИМЕЧАНИЕ: если нам не нужны новые столбцы, удалите часть .names

Если нам нужно сделать это в al oop, без привязки к одному data.frame, можно oop поверх list

library(purrr)
list(df1, df2, df3) %>% # // automatically => mget(ls('^df\\d+$'))
        map(~ .x %>%
          mutate(across(where(is.numeric), 
      ~(.- mean(., na.rm = TRUE))/sd(., na.rm = TRUE), .names = '{col}_zscore')))
1 голос
/ 06 августа 2020

Вот базовое решение R с функцией scale.

df_list <- list(df1, df2, df3)

df_list2 <- lapply(df_list, function(DF){
  i <- sapply(DF, is.numeric)
  DF[i] <- lapply(DF[i], scale)
  DF
})

методы S3

Учитывая, что scale является общим c и что для него можно написать методы, вот метод data.frame, затем применить к тому же списку df_list.

scale.data.frame <- function(x, center = TRUE, scale = TRUE){
  i <- sapply(x, is.numeric)
  x[i] <- lapply(x[i], scale, center = center, scale = scale)
  x
}

df_list3 <- lapply(df_list, scale)

identical(df_list2, df_list3)
#[1] TRUE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...