Вычислить медиану по нескольким спискам по вертикали

Скажем, у меня есть три списка, каждый из которых содержит результат теста:

listA <- list(10, 5, 4)
listB <- list(2, 8, 3)
listC <- list(1, 5, 3)

Я хочу найти медиану этих списков по положению по вертикали. Таким образом, результаты для каждой позиции будут:

  • Первая позиция: 2
  • Вторая позиция: 5
  • Третья позиция: 3

Как я могу добиться этого в R? Заранее спасибо.


person Natasha R.    schedule 12.09.2020    source источник


Ответы (4)


Вы можете использовать Map(), чтобы объединить три списка по вертикали, а затем вычислить каждую медиану с помощью lapply().

sapply(Map(c, listA, listB, listC), median)

# [1] 2 5 3

Вы также можете использовать transpose() из purrr.

library(purrr)

map_dbl(transpose(mget(ls(pattern = 'list'))), ~ median(flatten_dbl(.x)))

# [1] 2 5 3

Или используя pmap():

pmap_dbl(mget(ls(pattern = 'list')), ~ median(c(...)))

# [1] 2 5 3
person Darren Tsai    schedule 12.09.2020
comment
Это круто. Спасибо за предоставление как примера tidyverse, так и примера lapply. Еще один вопрос: скажем, мои три списка хранятся в виде столбца в кадре данных, где каждый список образует строку. Как изменится код, чтобы приспособиться к этому? - person Natasha R.; 12.09.2020
comment
@R.Baratheon Попробуйте purrr::pmap(df$var, ~ median(c(...))), где var - это столбец, в котором вы храните три списка. - person Darren Tsai; 12.09.2020
comment
Еще один вопрос... Скажем, я хочу определить, как часто заданный список содержит медианный результат. Как бы я это сделал? По сути, я пытаюсь рассчитать вероятность того, что список будет содержать средний результат. - person Natasha R.; 12.09.2020
comment
@ R.Baratheon Я не уверен в твоем вопросе. Вы имеете в виду 2 в listA, 5 в listB и 3 в listC? Если нет, приведите пример. - person Darren Tsai; 12.09.2020
comment
Извините, позвольте мне быть более конкретным. Мы знаем, что listA провел медиану один раз (5), listB провел медиану один раз (3), а listC провел медиану дважды (5 и 3). Таким образом, из трех списков listC занимал медиану два раза из трех. Мы бы сказали, что listC имеет 67% шансов удержать медиану. Мой первоначальный вопрос должен был состоять из двух частей теперь, когда я это пишу: как вычислить медиану (завершено благодаря вашей помощи), а затем как рассчитать вероятность медианы (изложено выше). Дайте мне знать, если вы считаете, что это лучше как отдельный вопрос. Спасибо еще раз. - person Natasha R.; 12.09.2020
comment
@R.Baratheon listB должен удерживать медиану дважды (2, 3), верно? Если я правильно понял правило, то попробуйте это sapply(mget(ls(pattern = 'list')), function(x) sum(unlist(x) %in% med)/length(x)), где "med" — это результат первого вопроса. Не забудьте сохранить его как вектор, то есть c(2, 5, 3), а не list(2, 5, 3). Если это все еще не помогает, задайте новый вопрос на SO, потому что это должен быть расширенный вопрос. - person Darren Tsai; 12.09.2020
comment
Я продолжу и опубликую новый вопрос. Спасибо еще раз. - person Natasha R.; 12.09.2020
comment
К вашему сведению, новый пост находится здесь: -r" title="как рассчитать вероятность быть медианой в списке с помощью r">stackoverflow.com/questions/63864013/ - person Natasha R.; 12.09.2020

Соберите все отдельные списки в один список, используя mget, объедините их в матрицу и возьмите медиану по строкам.

matrixStats::rowMedians(sapply(mget(ls(pattern = 'list')), unlist))
#[1] 2 5 3

Или сохранить его в базе R :

mat <- sapply(mget(ls(pattern = 'list')), unlist)
apply(mat, 1, median)
person Ronak Shah    schedule 12.09.2020

Мне пришлось немного изменить типы данных, чтобы заставить его работать, я мог бы сначала посмотреть другие ответы, но это то, что я сделал, чтобы получить то, что вы просили. Я поместил значения в векторы, а затем во фрейм данных вместо списка, а затем вызвал функцию median() для нужных вам респектабельных столбцов.

listA <- c(10, 5, 4)
listB <- c(2, 8, 3)
listC <- c(1, 5, 3)

test <- as.data.frame(rbind(listA, listB, listC))

median(test[,1])
[1] 2
median(test[,2])
[1] 5
median(test[,3])
[1] 3
person Daniel Jachetta    schedule 12.09.2020

Вариант с map и transpose

library(dplyr)
library(purrr)
mget(ls(pattern = ('^list[A-C]'))) %>% 
   transpose %>%
   map_dbl(~ flatten_dbl(.x) %>% median)
#[1] 2 5 3
person akrun    schedule 12.09.2020