by () дает ошибку при применении функции среднего к фрейму данных. Что творится?

Я пытаюсь изучить by() в R (3.0.1). Вот что я делаю.

  1. Открыть R
  2. attach(iris)
  3. head(iris)
  4. by(iris[,1:4] , Species , mean)

Это то, что я получаю

> by(iris[,1:4] , Species , mean)

Species: setosa
[1] NA
------------------------------------------------------------ 
Species: versicolor
[1] NA
------------------------------------------------------------ 
Species: virginica
[1] NA
Warning messages:
1: In mean.default(data[x, , drop = FALSE], ...) :
  argument is not numeric or logical: returning NA

2: In mean.default(data[x, , drop = FALSE], ...) :
  argument is not numeric or logical: returning NA

3: In mean.default(data[x, , drop = FALSE], ...) :
  argument is not numeric or logical: returning NA

person lovekesh    schedule 13.01.2014    source источник
comment
@Momo iris[1:4] не фактор. iris$Species - фактор, но тогда это то, чего хочет INDICES аргумент (или один из вариантов).   -  person Gavin Simpson    schedule 13.01.2014


Ответы (2)


Проблема здесь в том, что применяемая вами функция не работает с фреймом данных. По сути, вы вызываете что-то вроде этого

R> mean(iris[iris$Species == "setosa", 1:4])
[1] NA
Warning message:
In mean.default(iris[iris$Species == "setosa", 1:4]) :
  argument is not numeric or logical: returning NA

то есть вы передаете фрейм данных из 4 столбцов, содержащий строки оригинала, где Species == "setosa".

Для by() вам нужно сделать эту переменную по переменной, как в

R> by(iris[,1] , iris$Species , mean)
iris$Species: setosa
[1] 5.006
------------------------------------------------------------ 
iris$Species: versicolor
[1] 5.936
------------------------------------------------------------ 
iris$Species: virginica
[1] 6.588

Или используйте colMeans() вместо mean() в качестве примененного FUN

R> by(iris[,1:4] , iris$Species , colMeans)
iris$Species: setosa
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       5.006        3.428        1.462        0.246 
------------------------------------------------------------ 
iris$Species: versicolor
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       5.936        2.770        4.260        1.326 
------------------------------------------------------------ 
iris$Species: virginica
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       6.588        2.974        5.552        2.026

Если стандартной функции, такой как colMeans(), не существует, вы всегда можете написать оболочку для sapply(), например

foo <- function(x, ...) sapply(x, mean, ...)
by(iris[, 1:4], iris$Species, foo)

R> by(iris[, 1:4], iris$Species, foo)
iris$Species: setosa
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       5.006        3.428        1.462        0.246 
------------------------------------------------------------ 
iris$Species: versicolor
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       5.936        2.770        4.260        1.326 
------------------------------------------------------------ 
iris$Species: virginica
Sepal.Length  Sepal.Width Petal.Length  Petal.Width 
       6.588        2.974        5.552        2.026

Возможно, вам aggregate() более привлекательно:

R> with(iris, aggregate(iris[,1:4], list(Species = Species), FUN = mean))
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa        5.006       3.428        1.462       0.246
2 versicolor        5.936       2.770        4.260       1.326
3  virginica        6.588       2.974        5.552       2.026

Обратите внимание, как я использую with() для прямого доступа к Species; это намного лучше, чем attaching() iris, если вы не хотите индексировать через iris$Species.

person Gavin Simpson    schedule 13.01.2014
comment
Привет, спасибо за ответ. Но я следил за публикацией в блоге пользователя () и следовал инструкциям. Я делал то же самое и постоянно получал ошибку. А в документации by () относительно ввода данных говорится, что данные - объект R, обычно фрейм данных, возможно, матрица. Даже приведенный ниже пример, похоже, применяется к набору данных радужки. Блог, который я читал, находится здесь: nsaunders.wordpress.com/2010/08/20/ Можете ли вы сказать мне, почему реализация by () в блоге не дает ошибок ?? - person lovekesh; 14.01.2014
comment
@lovekesh mean() был изменен не так давно, поэтому он не работает с фреймом данных - поскольку этому сообщению более трех лет, я не удивлен, что он больше не работает. mean()sd()) были изменены, чтобы сделать язык более согласованным; легко написать sapply(foo, mean), чтобы получить старое поведение (или быстрее colMeans()), и есть ряд функций, похожих на mean() и sd(), которые не работали с фреймом данных (они должны были быть применяемый). - person Gavin Simpson; 14.01.2014
comment
Спасибо Гэвину за информацию и ответы. :) - person lovekesh; 14.01.2014

Еще одно решение, сочетающее в себе «сплит» и «саппли». Результат тот же, но транспонированный. Возможно, это предпочтительнее, когда отображается статистика для многих переменных, потому что они перечислены вертикально.

sapply (split (iris, iris [, 5]), function (x) colMeans (x [, c (1: 4)]))

                setosa versicolor virginica
   Sepal.Length  5.006      5.936     6.588
   Sepal.Width   3.428      2.770     2.974
   Petal.Length  1.462      4.260     5.552
   Petal.Width   0.246      1.326     2.026
person omd    schedule 26.11.2014