2016-10-19 3 views
0

Это мое первое сообщение в Stack Exchange, мои извинения, поскольку я уверен, что сделаю несколько ошибок. Я пытаюсь оценить ложные обнаружения в наборе данных.Поиск значения в пределах диапазона значений в двух отдельных векторах

У меня есть один кадр данных с «истинными» обнаружениями

truth= 
ID Start Stop SNR 
1 213466 213468 10.08 
2 32238 32240 10.28 
3 218934 218936 12.02 
4 222774 222776 11.4 
5 68137 68139 10.99 

И еще один кадром данных со списком времен, которые представляют собой возможные «реальные» обнаружения

возможных = ID Времен

1 32239,76

2 32241,14

3 68138,72

4 111233,93

5 128395,28

6 146180,31

7 188433,35

8 198714,7

Я пытаюсь увидеть, если значения в мой "возможный" кадр данных находится между значениями начала и останова. Если это так, я бы хотел создать третий столбец в возможном названии «между» и столбцом в фрейме данных «истина», который называется «match». Для каждого значения от возможного, которое находится между мной, мне нужен 1, иначе 0. Для всех строк в «истине», которые находят совпадение, мне нужен 1, в противном случае 0.

Ни один идентификатор, а не SNR важны. Я не ищу соответствия ID. пробежать кадра данных целиком Вывод должен выглядеть примерно так:.

ID времен Между

1 32239,76 0

2 32241,14 1

3 68138,72 0

4 111233,93 0

5 128395,28 0

6 146180,31 1

7 188433,35 0 ​​

8 198714,7 0

В качестве альтернативы, зная, может ли какое-либо из моих «возможных» значений времени находиться в пределах 2 секунд от времени начала или окончания, также будет делать трюк (также с выходами 1/0)

(Спасибо за отзыв на исходное сообщение)

Заранее благодарим вас за ваше терпение, когда я перемещаюсь по этой системе.

+0

Можете ли вы предоставить пример вывода. Является ли переменная SNR неактуальной? Вы хотите сравнивать строки только с теми же идентификаторами? –

+2

Ни один из ваших примеров не находится между началом или остановкой. Это не идеально подходит для тестирования. – thelatemail

+1

Возможно, что-то с 'findInterval'? - 'findInterval (c (213467,213500,218679,218679.5,100,400000), t (правда [c (« Старт »,« Стоп »)])) %% 2', похоже, работает нормально, например. – thelatemail

ответ

0

Я думаю, что это может быть conceptulised как прокатка вступить в data.table. Возьмите этот упрощенный пример:

truth 
# id start stop 
#1: 1  1 5 
#2: 2  7 10 
#3: 3 12 15 
#4: 4 17 20 
#5: 5 22 26 

possible 
# id times 
#1: 1  3 
#2: 2 11 
#3: 3 13 
#4: 4 28 

setDT(truth) 
setDT(possible) 
melt(truth, measure.vars=c("start","stop"), value.name="times")[ 
    possible, on="times", roll=TRUE 
    ][, .(id=i.id, truthid=id, times, status=factor(variable, labels=c("in","out")))] 

# id truthid times status 
#1: 1  1  3  in 
#2: 2  2 11 out 
#3: 3  3 13  in 
#4: 4  5 28 out 

Исходные наборы данных были:

truth <- read.table(text="id start stop 
1 1 5 
2 7 10 
3 12 15 
4 17 20 
5 22 26", header=TRUE) 

possible <- read.table(text="id times 
1 3 
2 11 
3 13 
4 28", header=TRUE) 
+0

Это не сработало для меня. Я получил следующую ошибку. –

+0

Ошибка в rep (x [[i]], length.out = mn): попытка репликации объекта типа 'замыкание' –

+0

Любые мысли? Спасибо! –

0

Я отправлю решение, которое, я уверен, работает так, как вы хотите, чтобы вы начали. Возможно, кто-то еще может опубликовать более эффективный ответ.

В любом случае, сначала мне нужно было сгенерировать некоторые данные примера - в следующий раз, пожалуйста, предоставьте это из своего собственного набора данных в своем сообщении, используя функцию dput(head(truth, n = 25)) и dput(head(possible, n = 25)). Я использовал:

#generate random test data 
set.seed(7) 
truth <- data.frame(c(1:100), 
        c(sample(5:20, size = 100, replace = T)), 
        c(sample(21:50, size = 100, replace = T))) 
possible <- data.frame(c(sample(1:15, size = 15, replace = F))) 
colnames(possible) <- "Times" 

После получения данных выборки для работы; следующее решение обеспечивает то, что, я считаю, вы просите. Это должно масштабироваться непосредственно к вашему собственному набору данных, поскольку оно, кажется, выложено. Ответьте ниже, если комментарии неясны.

#need the %between% operator 
library(data.table) 

#initialize vectors - 0 or false by default 
truth.match <- c(rep(0, times = nrow(truth))) 
possible.between <- c(rep(0, times = nrow(possible))) 

#iterate through 'possible' dataframe 
for (i in 1:nrow(possible)){ 
    #get boolean vector to show if any of the 'truth' rows are a 'match' 
    match.vec <- apply(truth[, 2:3], 
         MARGIN = 1, 
         FUN = function(x) {possible$Times[i] %between% x}) 
    #if any are true then update the match and between vectors 
    if(any(match.vec)){ 
     truth.match[match.vec] <- 1 
     possible.between[i] <- 1 
    } 
} 

#i think this should be called anyMatch for clarity 
truth$anyMatch <- truth.match 

#similarly; betweenAny 
possible$betweenAny <- possible.between 
Смежные вопросы