2017-02-17 14 views
1

Пусть у меня есть dataframe следующим образом,Найти минимальную разницу между столбца dataframe и вектором в R

a = c(10,20,30,40,50, 60, 70, 80 ,90, 100) %>% data.frame() 
colnames(a) = c("column1") 

и вектор,

b = c(46, 90, 75, 15) 

Я хочу, чтобы найти ближайший элемент Ь из а. Требуемая мощность будет,

a  b 
10 15 
20 15 
30 15 
40 46 
50 46 
60 46 
70 75 
80 75 
90 90 
100 90 

Ниже мой попытки,

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

a %>% add_rownames('rowname') %>% full_join(b %>% add_rownames(rowname), by = c("rowname" = "rowname")) 

Это не работает. Может ли кто-нибудь помочь мне в решении этой проблемы?

+2

'за $ Ь <- б [max.col (-abs (внешний (а $ column1, Ь \ '- \')))] ' – alistaire

+1

или в dplyr, так как он помечен,' a%>% rowwise()%>% mutate (b = b [who.min (abs (column1 - b))]) – alistaire

+0

@alistaire Спасибо. Вы хотите опубликовать его в качестве ответа? – Observer

ответ

1

Один из вариантов заключается в использовании outer с -, чтобы вычесть все комбинации элементов из каждого вектора, создавая матрицу. Переупорядочивая, чтобы найти отрицательное абсолютное значение этой матрицы, вы можете использовать max.col, чтобы узнать, какой индекс b имеет наименьшую разницу. Подменю b возвращает это значение, так

a$b <- b[max.col(-abs(outer(a$column1, b, `-`)))] 

возвращает

a 
## column1 b 
## 1  10 15 
## 2  20 15 
## 3  30 15 
## 4  40 46 
## 5  50 46 
## 6  60 46 
## 7  70 75 
## 8  80 75 
## 9  90 90 
## 10  100 90 

Вы могли одинаково работать поэлементно, если вы предпочитаете. В dplyr, группировка rowwise делает такой подход довольно прост:

library(dplyr) 

a %>% rowwise() %>% mutate(b = b[which.min(abs(column1 - b))]) 

## Source: local data frame [10 x 2] 
## Groups: <by row> 
## 
## # A tibble: 10 × 2 
## column1  b 
##  <dbl> <dbl> 
## 1  10 15 
## 2  20 15 
## 3  30 15 
## 4  40 46 
## 5  50 46 
## 6  60 46 
## 7  70 75 
## 8  80 75 
## 9  90 90 
## 10  100 90