根据因子的级别添加值

时间:2015-08-20 20:25:41

标签: r for-loop vectorization

我有这个可重现的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) 循环将不胜感激。

2 个答案:

答案 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.用于区分DataStart

中的相同列