2015-08-20 5 views
2

У меня есть эта воспроизводимые data.frame представляющих местоположения UTM для пяти особей (IndID), каждый из которых имеет 20 местДобавление значений на основе уровней фактора

РЕДАКТИРОВАТЬ: Различные ответы, как представляется, в результате запуска моего for() loop на unsorted data.frame. Я добавил код arrange df на IndID и теперь получаю те же ответы, что и вы.

library(plyr) 

set.seed(123) 
Data <- data.frame(IndID = rep(c("AAA", "BBB", "CCC", "DDD", "EEE"), 20), 
       UTM_E = sample(482000:509000, 100), 
       UTM_N = sample(4780000:4810500, 100) 
        ) 

Data <- arrange(Data, IndID) 

И у меня есть эта таблица, содержащая один Start места для каждого человека.

set.seed(123) 
Start <- data.frame(IndID = c("AAA", "BBB", "CCC", "DDD", "EEE"), 
       UTM_E = sample(482000:509000, 5), 
       UTM_N = sample(4780000:4810500, 5) 
        ) 

Для каждого уровня IndID Я хочу, чтобы применить следующий расчет, чтобы добавить новый столбец в Data. Например, когда Data$IndID == Start$IndID я хочу создать

Data$NewValue = ((((Data$UTM_E - Start$UTM_E)/1000)^2) + (((Data$UTM_N - Start$UTM_N)/1000)^2)) 

Хотя я знаю, что это возможно с после for() цикла и кода форматирования, я подозреваю, что существует лучший векторный подход, который был бы намного чище и эффективнее.

Inds <- unique(Data$IndID) 
NewValue <- list() 
for (i in 1:length(Inds)){ 
    NewValue[[i]] = ((((Data$UTM_E[Data$IndID == Inds[i]] - Start$UTM_E[i])/1000)^2) + 
      (((Data$UTM_N[Data$IndID == Inds[i]] - Start$UTM_N[i])/1000)^2)) 
        } 

Data$NewValue <- c(do.call("cbind",NewValue)) 

head(Data) 
tail(Data) 

Любые предложения о том, как «векторизовать» выше for() петли будут оценены.

+0

Замечание: если вы анализируете движение животных, вы можете взглянуть на пакет adehabitatLT. Очень легко получить базовые показатели из пространственно-временных данных, подобных вашим. См. [виньетка] (https://cran.r-project.org/web/packages/adehabitatLT/vignettes/adehabitatLT.pdf). – Henrik

+0

@ Хенрик. Да, пакет adehabitatLT замечательный, но для текущего проекта предпочтительным является формат объекта ltraj. –

ответ

2

Мы можем использовать merge, чтобы сделать один data.frame, то vectorise оттуда:

data2 <- merge(Data, Start, by = "IndID") 
data2$NewValue <- ((data2$UTM_E.x - data2$UTM_E.y)/1000)^2 + 
        ((data2$UTM_N.x - data2$UTM_N.y)/1000)^2 
+0

Вы могли получать те же значения, что и OP? Я получаю то же, что и ты, и очень отличаюсь от него. Вот почему я не опубликовал. –

+0

oh, вы правы - первое и последнее значения - это то же самое, что и все, что я проверил. – jeremycg

+1

@jeremycg вы должны быстро прочитать книги:} – rawr

2

Я бы рекомендовал использовать data.table сек двоичного присоединиться и обновление ссылочных возможностей для задачи

library(data.table) 
setkey(setDT(Data), IndID)[Start, NewValue := ((UTM_E - i.UTM_E)/1e3)^2 + 
               ((UTM_N - i.UTM_N)/1e3)^2] 

Примечание меня и @jeremycg получают разные результаты от вашего. Похоже, что у вас есть некоторая ошибка в ваших расчетах.


Идея здесь состоит в том, чтобы использовать общий столбец. выполнить бинарное соединение, и при объединении обновить столбец NewValue с использованием :=. i. перед именами колонок предназначен для различения между теми же колонками в Data и Start

Смежные вопросы