Обнаружение и извлечение имен из двоичного фрейма данных на основе процента дублирования - PullRequest
0 голосов
/ 19 июня 2020

У меня есть следующий фрейм данных:

df<-structure(list(species = structure(c(1L, 1L, 2L, 2L, 2L, 2L, 
                                         2L, 3L, 3L, 3L), .Label = c("a", "b", "c"), class = "factor"), 
                   sample1 = c(1L, 0L, 1L, 0L, 0L, 0L, 0L, 1L, 0L, 1L), sample2 = c(1L, 
                                                                                    1L, 1L, 1L, 0L, 0L, 1L, 0L, 0L, 1L), sample3 = c(0L, 0L, 
                                                                                                                                     0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                                                                           -10L))

Здесь дублируются значения столбца видов. 1/0 указывает на присутствие и отсутствие.

Для каждого образца я хочу подсчитать наличие повторяющихся видов при разном процентном значении. Например, допустим, мой процент отсечения равен 80. Количество дубликатов в a равно 2. 80% от 2 составляет 1,6 ~ 2 (ближайшее целое число). Точно так же количество дубликатов в b равно 5. 80% от 5 равно 4. Количество дубликатов в c равно 3. 80% от 3 составляет 2,4 ~ 2.

В каждом дубликате, если количество образцов (сумма единиц) больше или равна 80%, я напишу вид в образце.

Окончательный результат будет:

out_df<-structure(list(sample1 = structure(c(1L, 1L, 2L), .Label = c("0", 
"c"), class = "factor"), sample2 = structure(c(2L, 1L, 1L), .Label = c("0", 
"a"), class = "factor"), sample3 = c(0L, 0L, 0L)), class = "data.frame", row.names = c(NA, 
-3L))

Ответы [ 2 ]

1 голос
/ 19 июня 2020

Вот базовое решение R,

m1 <- sapply(split(df, df$species), function(i)1 * (colSums(i[-1]) >= round(nrow(i)*0.8)))
p1 <- which(m1 == 1, arr.ind = TRUE)
m1[p1] <- colnames(m1)[p1[,'col']]

as.data.frame(t(m1))

#  sample1 sample2 sample3
#a       0       a       0
#b       0       0       0
#c       c       0       0
1 голос
/ 19 июня 2020

Вот способ использования dplyr:

library(dplyr)
threshold <- 0.8

df1 <- df %>%
  add_count(species) %>%
  mutate(n = round(n * threshold)) %>%
  group_by(species) %>%
  summarise(across(sample1:sample3, ~sum(.) >= first(n))) %>% 
  #In old dplyr you can use `summarise_at`
  #summarise_at(vars(sample1:sample3), ~sum(.) >= first(n))
  data.frame()

#  species sample1 sample2 sample3
#1       a   FALSE    TRUE   FALSE
#2       b   FALSE   FALSE   FALSE
#3       c    TRUE   FALSE   FALSE

Чтобы получить такой же результат, как показано:

mat <- which(as.matrix(df1[-1]), arr.ind = TRUE)
df1[-1][!df1[-1]] <- NA
df1[-1][mat] <- as.character(df1$species[mat[, 1]])
df1[-1]

#   sample1 sample2 sample3
#1     <NA>       a      NA
#2     <NA>    <NA>      NA
#3       c     <NA>      NA
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...