Группировать и сравнивать числа в списке - PullRequest
1 голос
/ 05 февраля 2020

Рассмотрим следующий кадр данных, полученный после операции cbind в двух списках

> fl
  x meanlist
1 1     48.5
2 2     32.5
3 3     28.0
4 4     27.0
5 5     25.5
6 6     20.5
7 7     27.0
8 8     24.0

class_median <- list(0, 15, 25, 35, 45)
class_list <- list(0:10, 10:20, 20:30, 30:40, 40:50)

Значения в class_median представляют классы от -10 до +10, от 10 до 20, от 20 до 30 и т. Д. c

Во-первых, я пытаюсь сгруппировать значения в fl$meanlist согласно классам в class_list. Во-вторых, я пытаюсь вернуть одно значение для класса, которое ближе всего к срединным значениям, следующим образом

> fl_subset
  x meanlist cm
1 1     48.5 45
2 2     32.5 35
3 5     25.5 25

Я пытаюсь использовать циклы для сравнения, но оно кажется длинным и неуправляемым, и результат не правильно

Ответы [ 2 ]

2 голосов
/ 05 февраля 2020

Вот подход с dplyr:

library(dplyr)

# do a little prep--name classes, extract breaks, put medians in a data frame
names(class_list) = letters[seq_along(class_list)]
breaks = c(min(class_list[[1]]), sapply(class_list, max))
med_data = data.frame(median = unlist(class_median), class = names(class_list))


fl %>% 
  # assign classes
  mutate(class = cut(meanlist, breaks = breaks, labels = names(class_list))) %>%
  # get medians
  left_join(med_data) %>%
  # within each class...
  group_by(class) %>%
  # keep the row with the smallest absolute difference to the median
  slice(which.min(abs(meanlist - median))) %>%
  # sort in original order
  arrange(x)

# Joining, by = "class"
# # A tibble: 3 x 4
# # Groups:   class [3]
#       x meanlist class median
#   <int>    <dbl> <fct>  <dbl>
# 1     1     48.5 e         45
# 2     2     32.5 d         35
# 3     5     25.5 c         25
0 голосов
/ 05 февраля 2020

Один подход с использованием purrr и dplyr может быть:

map2(.x = class_list,
     .y = class_median, 
     ~ fl %>%
      mutate(cm = between(meanlist, min(.x), max(.x))) %>%
      filter(any(cm)) %>%
      mutate(cm = cm*.y)) %>%
 bind_rows(.id = "ID") %>%
 group_by(ID) %>%
 slice(which.min(abs(meanlist-cm)))



  ID        x meanlist    cm
  <chr> <int>    <dbl> <dbl>
1 3         5     25.5    25
2 4         2     32.5    35
3 5         1     48.5    45
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...