R: найти ближайшее наблюдение к средним значениям

У меня есть таблица со статистикой описания (значения для a, b и c) по типу

### stats
type <- c("a","b","c","d","e","f","g","h","i","j","k","l")
mean_a <- c(0,1,1,0,2,2,0,4,4,0,5,5)
mean_b<- c(4,7,8,0,3,10,5,4,7,0,1,6)
mean_c<- c(1,2,0,3,4,5,1,24,3,0,4,5)
stats <- data.frame(type, mean_a, mean_b, mean_c)

У меня есть набор данных с наблюдениями за образцом для параметров a, b и c. Каждый из экземпляров имеет определенный тип

# data
Id <- c("ted","bert","test","john","elf","fea","goul","houl","ili","jok","ko","lol")
type <- c("a","a","b","d","f","f","c","d","a","b","k","l")
a <- c(2,1,3,2,1,2,0,1,2,1,5,5)
b<- c(1,3,4,7,5,4,5,6,5,0,1,6)
c<- c(3,5,2,6,8,5,1,5,3,1,6,6)
data <- data.frame(Id, type, a, b, c )

Следуя этим двум таблицам, я хотел бы получить от data образец, наиболее представительный для типа, согласно статистике в stats. Наиболее репрезентативным я хотел бы получить тот, у которого значения a, b и c наиболее близки к их соответствующим средним значениям.

Я не могу найти в Интернете идеи, соответствующие трем средним значениям (а, б и в). Помощь приветствуется! Требуемый результат (но не уверен, что ted, test и john ближе всего к средним значениям для типов a, b и c):

# output wanted
Id <- c("ted","test","john")
type <- c("a","b","c")
a <- c(2,3,2)
b<- c(1,4,7)
c<- c(3,2,6)
data2 <- data.frame(Id, type, a, b, c )

person Floni    schedule 07.09.2016    source источник
comment
Итак, каков будет ожидаемый результат в этом случае? (отредактируйте ожидаемый результат в вашем вопросе)   -  person Sotos    schedule 07.09.2016


Ответы (2)


«Наиболее представительный», как вы упомянули, сам по себе очень расплывчатый, но вот попытка найти разницу между значениями из data и средними значениями из stats и сохранить значение с наименьшим средним значением. Поскольку я присоединил кадры данных заранее, вы можете использовать функцию select() в конце кода и изменить (сохранить/удалить переменные) соответствующим образом.

library(dplyr)
df1 <- merge(data1, stats, by = 'type')
df1 %>% 
  mutate(new = abs(rowMeans(mapply(`-`, df1[,(3:5)], df1[,(6:8)])))) %>% 
  group_by(type) %>% 
  filter(new == min(new)) %>% 
  select(-new)

#Source: local data frame [7 x 8]
#Groups: type [7]

#    type     Id     a     b     c mean_a mean_b mean_c
#  <fctr> <fctr> <dbl> <dbl> <dbl>  <dbl>  <dbl>  <dbl>
#1      a    ted     2     1     3      0      4      1
#2      b   test     3     4     2      1      7      2
#3      c   goul     0     5     1      1      8      0
#4      d   houl     1     6     5      0      0      3
#5      f    elf     1     5     8      2     10      5
#6      k     ko     5     1     6      5      1      4
#7      l    lol     5     6     6      5      6      5
person Sotos    schedule 07.09.2016
comment
не могли бы вы немного подробнее объяснить, что такое mapply(-, df1[,(3:5)], df1[,(6:8)])))? Это pselect соответствующий столбец, который вы хотите получить на выходе? - person Floni; 07.09.2016
comment
Понял, он отлично работает с редактированием df1[,(3:5)], df1[,(6:8)]))) на хорошие номера столбцов - person Floni; 07.09.2016
comment
@Floni mapply сопоставляет интересующие столбцы один к одному, поэтому df1[,3] с df1[,6] и так далее - person Sotos; 07.09.2016

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

data$dist <- (data$a - stats[data$type, "mean_a"])^2 + 
             (data$b - stats[data$type, "mean_b"])^2 +
             (data$c - stats[data$type, "mean_c"])^2 
closest <- which.min(data$dist)
print(paste0("Closest is number ",closest, ": ",data[closest, "Id"] ))
person Bernhard    schedule 07.09.2016
comment
Квадратичная мера может подойти, но вы полностью игнорируете информацию о группировке (type) в своем ответе. - person talat; 07.09.2016
comment
@docendo discimus Когда я написал свой код. оригинальный постер еще не ответил на запрос Сотоса об ожидаемом результате. Мой подход можно расширить, чтобы получить не один результат, а один результат для каждой группы. Однако, когда я увидел добавленный ожидаемый результат, уже был принятый ответ. - person Bernhard; 07.09.2016