2013-02-08 44 views
5

Tôi có một khung dữ liệu với ba cột: ref, target, distance. Mỗi ref có khoảng cách được đo tới cùng một tập hợp các mục tiêu và tôi muốn lấy một vectơ khoảng cách tối thiểu cho mỗi ref. Ngay bây giờ tôi đang làm điều này với một vòng lặp for, nhưng nó có vẻ như có phải là một cách để vectorize này.Vectorize cho vòng lặp qua khung dữ liệu trong R

Dưới đây là mã của tôi:

refs <- levels(data$ref) 

result <- c() 
for (ref in refs) { 
    # Find the minimum distance for observations with the current ref 
    # but be sure to protect against ref == target! 
    best_dist <- min(data[data$ref == ref & data$target != ref,]$distance) 
    result <- c(result, best_dist) 
} 

Am Tôi cam chịu bởi có khung dữ liệu của tôi thiết lập theo cách này hoặc là có một cách tốt để vectorize này? Cảm ơn đã giúp đỡ!

Trả lời

6

Không bao giờ phát triển đối tượng trong vòng lặp sử dụng c, cbind, rbind. Đối tượng sẽ được sao chép mọi lúc. Thay vào đó preallocate với kích thước chính xác (hoặc một số đánh giá quá cao nếu kết quả là chất lỏng).

Điều đó đang được nói, một vòng lặp không cần thiết ở đây

Tôi thích data.table s cho hiệu quả bộ nhớ và mã hóa sang trọng.

library(data.table) 
DT <- data.table(data) 


DT[ref != target, list(bestdist = min(distance)), by = ref] 

nếu ref và mục tiêu là cột yếu tố với các mức độ khác nhau (như đề xuất trong các bình luận), sau đó, hoặc làm cho họ có mức độ giống nhau, hoặc chuyển đổi sang nhân vật

DT[as.character(ref) != as.character(target), list(bestdist = min(distance)), by = ref] 
+0

Tôi nghĩ rằng bạn có một ')' thiếu ở đó ... – adibender

+0

ta. Sửa lỗi ngay bây giờ .. – mnel

+0

Điều này có vẻ không hoạt động tốt như hiện tại. Tôi nhận được lỗi sau khi thử điều này: ** Lỗi trong Ops.factor (ref, target): tập hợp các yếu tố khác nhau ** Tuy nhiên, ** DT [, list (bestdist = min (distance)), by = ref] ** Sản xuất đầu ra, nhưng không có kiểm tra ref! = target. – weitzner

Các vấn đề liên quan