Как применить функцию к подмножеству столбцов в r? - PullRequest
6 голосов
/ 01 марта 2012

Я использую by для применения функции к столбцам диапазона фрейма данных на основе фактора. Все отлично работает, если я использую mean() в качестве функции, но если я использую median(), я получаю ошибку типа «Ошибка в median.default (x): нужны числовые данные» , даже если я нет данных в фрейме данных.

Строка, которая работает с использованием mean():

by(iris[,1:3], iris$Species, function(x) mean(x,na.rm=T))

> by(iris[,1:3], iris$Species, function(x) mean(x,na.rm=T))
iris$Species: setosa
Sepal.Length  Sepal.Width Petal.Length 
       5.006        3.428        1.462 
------------------------------------------------------------ 
iris$Species: versicolor
Sepal.Length  Sepal.Width Petal.Length 
       5.936        2.770        4.260 
------------------------------------------------------------ 
iris$Species: virginica
Sepal.Length  Sepal.Width Petal.Length 
       6.588        2.974        5.552 
Warning messages:
1: mean(<data.frame>) is deprecated.
 Use colMeans() or sapply(*, mean) instead. 
2: mean(<data.frame>) is deprecated.
 Use colMeans() or sapply(*, mean) instead. 
3: mean(<data.frame>) is deprecated.
 Use colMeans() or sapply(*, mean) instead. 

Но если я использую median() (обратите внимание на na.rm=T option):

> by(iris[,1:3], iris$Species, function(x) median(x,na.rm=T))
Error in median.default(x, na.rm = T) : need numeric data

Однако, если вместо выбора диапазона [,1:3] столбцов я выберу только один из столбцов, он работает:

> by(iris[,1], iris$Species, function(x) median(x,na.rm=T))
iris$Species: setosa
[1] 5
------------------------------------------------------------ 
iris$Species: versicolor
[1] 5.9
------------------------------------------------------------ 
iris$Species: virginica
[1] 6.5

Как мне добиться такого поведения при выборе диапазона столбцов?

Ответы [ 2 ]

4 голосов
/ 01 марта 2012

При использовании by вы используете стратегию раздельного применения. Объекты, передаваемые в функцию, являются фреймами данных, и вы получаете предупреждение и ошибку из-за несуществования median.data.frame и надвигающегося несуществования mean.data.frame. Это может работать лучше, если вы используете aggregate:

> aggregate(iris[,1:3], iris["Species"], function(x) mean(x,na.rm=T))
     Species Sepal.Length Sepal.Width Petal.Length
1     setosa        5.006       3.428        1.462
2 versicolor        5.936       2.770        4.260
3  virginica        6.588       2.974        5.552
> aggregate(iris[,1:3], iris["Species"], function(x) median(x,na.rm=T))
     Species Sepal.Length Sepal.Width Petal.Length
1     setosa          5.0         3.4         1.50
2 versicolor          5.9         2.8         4.35
3  virginica          6.5         3.0         5.55

aggregate работает с векторами столбцов индивидуально, а затем табулирует результаты.

1 голос
/ 14 августа 2017

На оригинальный вопрос дан ответ. Однако, если диапазон оказывается (вместо) всех столбцов, кроме тех, которые указаны как независимая переменная в формуле, нотация точечной формулы работает и представляет изящную альтернативу:

> aggregate(. ~ Species, data = iris, 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

> aggregate(. ~ Species, data = iris, median)
     Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1     setosa          5.0         3.4         1.50         0.2
2 versicolor          5.9         2.8         4.35         1.3
3  virginica          6.5         3.0         5.55         2.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...