我有这个可重现的data.frame
代表五个人(IndID
)的UTM位置,每个人都有20个位置
编辑:在未排序的for()
上运行我的data.frame.
循环似乎会产生不同的答案我已将代码添加到arrange
df {{1} 1}}现在得到与你相同的答案。
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
对于每个级别的IndID,我想应用以下计算来在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)
)
中添加新列。例如,当我想创建Data.
时
Data$IndID == Start$IndID
虽然我知道使用以下Data$NewValue = ((((Data$UTM_E - Start$UTM_E)/1000)^2) + (((Data$UTM_N - Start$UTM_N)/1000)^2))
循环和格式化代码可以实现这一点,但我怀疑有更好的矢量方法会更清晰,更有效。
for()
有关如何向量化&#39;的任何建议上述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)
循环将不胜感激。
答案 0 :(得分:2)
我们可以使用merge
创建一个data.frame,然后从那里进行矢量化:
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
答案 1 :(得分: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