2014-01-02 3 views
0

Я использую алгоритм, который выглядит следующим образом:

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) 
} 

Проблема заключается в том, что, когда я называю эту функцию с тусклым = 1 я иногда получаю «Оператор $ недействительна для атомных векторов ». Есть ли способ вызвать столбцы из фреймов данных, которые не подведут меня? Чтобы быть более конкретным: могу ли я вызвать функцию f, назначающую пустые метки?

+0

Возможно, что вы испытываете [это] (http://stackoverflow.com/q/7938883/324364). – joran

+1

Я должен отметить, что это просто предположение, поскольку ваш пример не воспроизводится. Мало того, что это не воспроизводимо, вы даже не указали информацию о том, где именно произошла ошибка. – joran

+0

Я отметил это как дубликат связанного вопроса joran, который должен иметь хороший ответ о том, почему это происходит. Хотя я считаю, что код лучше всего реорганизован без цикла for (что я не уверен на 100%). –

ответ

0

Вы ищете что-то вроде этого?

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 
Смежные вопросы