0

I'm using an algorithm that looks like this:

df <- read.table(sep=" ", header=T, text="
x y z label
1 3 2 a
2 4 4 b
3 8 5 c
4 5 6 a
5 1 8 f")


f <- function(refObs, label) {
  d <- vector()
  for (i in which(df$label==label))   
    d <- c(d, dist(rbind (refObs, df[i,1:dim]) , method ="euclidean") )
  return(dist)
}

Problem is that when I call this function with dim=1 I sometimes get "$ operator is invalid for atomic vectors". Is there a way to call columns from dataframes that won't fail me? To be more specific: can I call the f function assigning empty labels?

user3083324
  • 585
  • 8
  • 23
  • Probably what you are experiencing is [this](http://stackoverflow.com/q/7938883/324364). – joran Jan 02 '14 at 23:08
  • 1
    I should note that that's just a guess, though, since your example isn't reproducible. Not only is this not reproducible, you haven't even provided information about where specifically the error occurred. – joran Jan 02 '14 at 23:13
  • I flagged this as a duplicate of the question joran linked, which should have a good answer as to why this is happening. Though I think the code is best refactored without a for loop (which I'm not 100% sure is necessary). – Adam Hyland Jan 02 '14 at 23:16
  • So what do u suggest instead of a for loop? – user3083324 Jan 02 '14 at 23:20
  • Just to be specific: `df[i,1:dim,drop=FALSE]` – Ben Bolker Jan 03 '14 at 00:06

1 Answers1

0

Are you looking for something like this?

f <- function(df, refObs, label=NULL) {
  df <- as.data.frame(df)
  d <- vector()
  if (is.null(label) | !"label" %in% names(df)) { 
    rows <- 1:nrow(df)
  } else
    rows <- which(df$label==label)
  if (length(refObs) != length(which(names(df) != "label")))
    stop("refObs too short or too long")
  for (i in rows)   
    d <- c(d, dist(rbind(refObs, df[i,1:length(refObs)]), method ="euclidean"))
  return(d)
}


f(df, c(1,3,2), "a")
# [1] 0.000000 5.385165
f(df, c(1,3,2))
# [1] 0.000000 2.449490 6.164414 5.385165 7.483315
df <- df[,1]
f(df, 1)
# [1] 0 1 2 3 4
lukeA
  • 53,097
  • 5
  • 97
  • 100