как вычесть значение из одного столбца из значения из предыдущей строки, другого столбца в r

У меня есть фреймворк, состоящий из 3 столбцов и ~ 2000 строк.

ID    DistA    DistB    
1    100    200    
2    239    390    
3    392    550    
4    700    760    
5    770    900

Первый столбец (ID) - это уникальный идентификатор для каждой строки. Я бы хотел, чтобы мой сценарий читал каждую строку и вычитал / сравнивал значение из столбца «DistA» в каждой строке из значения столбца «DistB» из предыдущей строки. Если разница расстояний между любыми последующими парами составляет ‹40, вывести, что они находятся в одной области. Например: В приведенном выше примере сравнения строк 2 и 1, «239» из строки 2 и «200» из строки 1 равно ‹40 и, следовательно, находятся в той же области. Таким же образом 2 и 3 находятся в одной области, т.е. разница составляет 2 и 2 ‹40. Но строки 3 и 4 не такие, так как разница в 150.

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

Я новичок в R, и это код «новичка», который у меня есть. Где я ошибаюсь. Заранее спасибо:

#the function to compare the two columns
funct <- function(x){
    for(i in 1:(nrow(dat)))
    (as.numeric(dat$DistA[i-1])) - (as.numeric(dat$DistB[i]))}

#creating a new column 'new2' with the differences
dat$new2 <- apply(dat[,c('DistB','DistA')]),1, funct

Когда я запускаю это, я получаю следующую ошибку:

Error: unexpected ',' in "dat$new2 <- apply(dat[,c('DistB','DistA')]),"

Буду признателен за все комментарии / предложения.


person Anita    schedule 14.03.2015    source источник
comment
Привет, я бы попытался скопировать столбец B в отдельную переменную, сдвинуть его, а затем вычесть его обычным способом. В любом случае, проверяйте скобки при вызове заявки.   -  person questing    schedule 14.03.2015
comment
Попробуйте library(dplyr) ; df %>% mutate(Dist = ifelse(abs(DistA - lag(DistB)) < 40, "Same", "Diff"))   -  person David Arenburg    schedule 14.03.2015


Ответы (2)


Я считаю, что здесь вам может помочь dplyr.

library(dplyr)

dfData <- data.frame(ID = c(1, 2, 3, 4, 5), 
                     DistA = c(100, 239, 392, 700, 770), 
                     DistB = c(200, 390, 550, 760, 900))

dfData <- mutate(dfData, comparison = DistA - lag(DistB))

Это приводит к ...

dfData
  ID DistA DistB comparison
1  1   100   200         NA
2  2   239   390         39
3  3   392   550          2
4  4   700   760        150
5  5   770   900         10

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

person Olivier Dupuis    schedule 15.03.2015

Мы также могли бы попробовать data.table (аналогично подходу, предложенному в комментариях @David Arenburg). shift - это новая функция, представленная в версии devel с type='lag' в качестве параметра по умолчанию. Его можно установить здесь

library(data.table)#data.table_1.9.5
setDT(df1)[, Categ := c('Diff', 'Same')[
             (abs(DistA-shift(DistB)) < 40 )+1L]][]
 #   ID DistA DistB Categ
 #1:  1   100   200   NA
 #2:  2   239   390 Same
 #3:  3   392   550 Same
 #4:  4   700   760 Diff
 #5:  5   770   900 Same

Если нам нужны столбцы "разница" и "категория"

setDT(df1)[,c('Dist', 'Categ'):={tmp= abs(DistA-shift(DistB))
               list(tmp, c('Diff', 'Same')[(tmp <40)+1L])}]
 df1
 #   ID DistA DistB Dist Categ
 #1:  1   100   200   NA    NA
 #2:  2   239   390   39  Same
 #3:  3   392   550    2  Same
 #4:  4   700   760  150  Diff
 #5:  5   770   900   10  Same
person akrun    schedule 15.03.2015