2014-10-06 6 views
3

Я пытаюсь объединить некоторые данные, которые являются как числовыми, так и переменными факторов. Если переменная является числовой, мне бы хотелось иметь среднее значение. Если это фактор, я бы хотел получить наиболее частое значение. Я написал следующую функцию, но я не получаю выход я хотел бы:R: агрегат на основе коэффициента или числового

meanOrMostFreq <- function(x){ 
    if(class(x) == 'factor'){ 
    tbl <- as.data.frame(table(x)) 
    tbl$Var1 <- as.character(tbl$Var1) 
    return(tbl[tbl$Freq == max(tbl$Freq),'Var1'][1]) 
    } 
    if(class(x) == 'numeric'){ 
    meanX <- mean(x, na.rm = TRUE) 
    return(meanX) 
    } 
} 

Вот как я использую его:

df1 <- iris[1:148,] 
df1$letter1 <- as.factor(rep(letters[1:4], 37)) 

momf <- aggregate(.~ Species, df1, FUN = function(x) meanOrMostFreq(x)) 

И результаты:

> momf 
    Species Sepal.Length Sepal.Width Petal.Length Petal.Width letter1 
1  setosa  5.006000 3.428000  1.462000  0.246 2.46 
2 versicolor  5.936000 2.770000  4.260000  1.326 2.54 
3 virginica  6.610417 2.964583  5.564583  2.025 2.50 

Я надеюсь получить фактическое письмо в последнем столбце вместо числа. Любые предложения о том, что я делаю неправильно?

+0

Уверен 'aggregate' не будет играть с не-числовых значений. Вам может понадобиться другой инструмент. – joran

+0

Вы можете легко достичь того, чего хотите, с помощью 'data.table'. Во всяком случае, в вашем 'meanOrMostFreq' есть некоторые ошибки. Во-первых, это должно быть 'as.data.frame (table (x))'. Тогда получившийся столбец будет называться 'x' вместо' Var'. Вы не видите эти ошибки в своем вызове 'aggregate', поскольку он принуждает к числовому. Просто попробуйте 'meanOrMostFreq (df1 $ letters)'. – nicola

+0

@nicola: вы правы на столе (x) и var vs Var1. Я внес изменения, и я все равно получаю те же ошибки. – screechOwl

ответ

5

Вот способ использования data.table

library(data.table) 
setDT(df1)[ ,lapply(.SD, function(x) if(is.numeric(x)) mean(x, na.rm=TRUE) else 
      names(which.max(table(x)))) , by=Species] 

#   Species Sepal.Length Sepal.Width Petal.Length Petal.Width letter1 
#1:  setosa  5.006000 3.428000  1.462000  0.246  a 
#2: versicolor  5.936000 2.770000  4.260000  1.326  c 
#3: virginica  6.610417 2.964583  5.564583  2.025  a 
1

Проходя по формуле интерфейс к aggregate по-видимому, теряет метаданные, которые его одним из факторов; это работает для меня:

> meanOrMostFreq 
function(x){ 
    if(class(x) == 'factor'){ 
    return( names(which.max(table(x)))) 
    } 
    if(class(x) == 'numeric'){ 
    meanX <- mean(x, na.rm = TRUE) 
    return(meanX) 
    } 
} 
> aggregate(df1[-5], df1[5], meanOrMostFreq) 
    Species Sepal.Length Sepal.Width Petal.Length Petal.Width letter1 
1  setosa  5.006000 3.428000  1.462000  0.246  a 
2 versicolor  5.936000 2.770000  4.260000  1.326  c 
3 virginica  6.610417 2.964583  5.564583  2.025  a 

Поскольку существует различное поведение для aggregate.formula и aggregate.data.frame это чувствует, как ошибка для меня.

1

альтернатива использования plyr пакет:

ddply(df1, .(Species), function(df) { 
    sapply(df, meanOrMostFreq) 
}) 

[] s

Смежные вопросы