AIM: I want to automate (loop) the code below, without having to manually run it for each sample. I have a terrible habit of writing long-hand in base, and need to start using loops, which I find difficult to implement.
DATA: I have two data frames: one of the sample data (samples), and one of reference data (ref). They both contain the same variables (x, y, z).
CODE DESCRIPTION: For each sample (sample$sample_name), I want to calculate it's Euclidean distance to each case in the reference data. The results are then used to re-order the reference data, to show which points are 'closest' to the sample data point, in the Euclidean (3-dimensional) space.
My current code allows me to simply substitute the sample name (i.e. "s1") and then re-run the code, making one final change for the filename of the .csv file. The output is a list of the reference data in order of closest proximity to the sample (in the Euclidean space).
I would like to automate the process (into a loop?), so that I can simply run it on the two data frames using the list of sample names (samples$sample_name), and hopefully also automate the exporting to a .csv file.
Any help would be greatly appreciated!
# Reference data
country<-c("Austria","Austria","Italy","Italy","Turkey","Romania","France")
x<-c(18.881,18.881,18.929,19.139,19.008,19.083,18.883)
y<-c(15.627,15.627,15.654,15.772,15.699,15.741,15.629)
z<-c(38.597,38.597,38.842,39.409,39.048,39.224,38.740)
pb_age<-c(-106,-106,-87,-6,-55,-26,-104)
ref<-data.frame(country,x,y,z,pb_age) # Reference data
# Sample data (for euclidean measurements against Reference data)
sample_name<-c("s1","s2","s3")
x2<-c(18.694,18.729,18.731)
y2<-c(15.682,15.683,15.677)
z2<-c(38.883,38.989,38.891)
pb_age2<-c(120,97,82)
samples<-data.frame(sample_name,x2,y2,z2,pb_age2) # Sample data
colnames(samples)<-c("sample_name","x","y","z","pb_age") # To match Reference data headings
# Euclidean distance measurements
library(fields) # Need package for Euclidean distances
# THIS IS WHAT I WANT TO AUTOMATE/LOOP (BELOW)...
# Currently, I have to update the 'id' for each sample to get a result (for each sample)
id<-"s1" # Sample ID - this is simply changed so the following code can be re-run for each sample
# The code
x1<-samples[which(samples$sample_name==id),c("x","y","z")]
x2<-ref[,c("x","y","z")]
result_distance<-rdist(x1,x2) # Computing the Euclidean distance
result_distance<-as.vector(result_distance) # Saving the results as a vector
euclid_ref<-data.frame(result_distance,ref) # Creating a new data.frame adding the Euclidean distances to the original Reference data
colnames(euclid_ref)[1]<-"euclid_distance" # Updating the column name for the result
# Saving and exporting the results
results<-euclid_ref[order(euclid_ref$euclid_distance),] # Re-ordering the data.frame by the euclide distances, smallest to largest
write.csv(results, file="s1.csv") # Ideally, I want the file name to be the same as the SAMPLE id, i.e. s1, s2, s3...