2010-12-05 2 views
2

Я борюсь с чем-то очень простым, но я собираюсь по кругу и просто не вижу, где я делаю ошибку. Я очень надеюсь, что кто-то может предложить мне удобное предложение, чтобы я больше не застрял!Вычисление процентов в заявлении о применении (R)

Моя цель: Я хочу рассчитать процент экземпляров в data.frame, который имеет результат выше 0. Я пробовал это с циклом for, но безрезультатно. Итак, после некоторого поиска я использовал функцию apply для вычисления различных показателей как средних, sd и min/max. Это отлично работает, но для вычисления процента функция приложения не работает, даже когда я создаю пользовательскую функцию и вставляю ее в функцию apply.

Это сокращенная версия моего data.frame:

 tradesList[c(1:5,10:15),c(1,7)] 
    Instrument TradeResult.Currency. 
1   JPM     -3 
2   JPM     264 
3   JPM     284 
4   JPM     69 
5   JPM     283 
10  JPM     -294 
11  KFT     -8 
12  KFT     -48 
13  KFT     125 
14  KFT     -150 
15  KFT     -206 

Я хочу обобщить эту data.frame, например, показывая средний TradeResult для каждого инструмента:

> tapply(tradesList$TradeResult.Currency., tradesList$Instrument, mean) 
JPM KFT 
42.3 14.6 

Однако , Я также хотел бы рассчитать процент строк, которые имеют TradeResult> 0 за инструмент. Однако, если функция «какая», проверяющая экземпляры, которые работают> 0, работает, не будет принимать эту функцию в качестве аргумента.

> length(which(tradesList$TradeResult.Currency. > 0))/length(tradesList$TradeResult.Currency.) * 100 
[1] 50 
> tapply(tradesList$TradeResult.Currency., tradesList$Instrument, (length(which(tradesList$TradeResult.Currency. > 0))/length(tradesList$TradeResult.Currency.) * 100)) 
Error in match.fun(FUN) : 
    c("'(length(which(tradesList$TradeResult.Currency. > 0))/length(tradesList$TradeResult.Currency.) * ' is not a function, character or symbol", "' 100)' is not a function, character or symbol") 
> 

Я искал в функции справки для получения дополнительной информации об этой ошибке, и пытались различными способами формулирования функции (например, при помощи кронштейнов или кавычки), но каждый способ приводит к тому же результату.

Кто-нибудь знает, кто хочет вычислить процент экземпляров, которые больше нуля? Может, я что-то упустил?

Большое спасибо заранее,

С уважением,

Edit: Большое спасибо за ваши быстрые комментарии G. гротендиковых, Гэвин Симпсон и Двине. Очень ценится и очень полезно!

Решено: Вот что я сейчас:

> tmpData <- tradesList[c(1:5,10:15),c(1,7)] 
> tmpData 
    Instrument TradeResult.Currency. 
1   JPM     -3 
2   JPM     264 
3   JPM     284 
4   JPM     69 
5   JPM     283 
10  JPM     -294 
11  KFT     -8 
12  KFT     -48 
13  KFT     125 
14  KFT     -150 
15  KFT     -206 
> 100* # to get percentages 
+ with(tmpData, 
+ tapply((TradeResult.Currency. > 0) , Instrument, sum)/ # number GT 0 
+  tapply(TradeResult.Currency., Instrument, length)) # total number 
    JPM  KFT 
66.66667 20.00000 
> 100 * tapply(tmpData$TradeResult.Currency. > 0, tmpData$Instrument, mean) 
    JPM  KFT 
66.66667 20.00000 
> pcentFun <- function(x) { 
+  res <- x > 0 
+  100 * (sum(res)/length(res)) 
+ } 
> 
> with(tmpData, tapply(TradeResult.Currency., Instrument, pcentFun)) 
    JPM  KFT 
66.66667 20.00000 

Еще раз спасибо!

С уважением,

ответ

2

Написать простую функцию, чтобы сделать вычисление:

pcentFun <- function(x) { 
    res <- x > 0 
    100 * (sum(res)/length(res)) 
} 

Тогда мы можем применить это к группам инструментов, с помощью tapply()

> with(tradeList, tapply(TradeResult.Currency, Instrument, pcentFun)) 
    JPM  KFT 
66.66667 20.00000 

но aggregate() будет более полезным, если вы хотите, резюме с названиями приборов:

> with(tradesList, aggregate(TradeResult.Currency, 
+       by = list(Instrument = Instrument), pcentFun)) 
    Instrument  x 
1  JPM 66.66667 
2  KFT 20.00000 
+0

Спасибо, Гэвин, это действительно полезно. Совокупное предложение - это также кое-что, что я могу использовать для остальной части моего анализа R. Большой! – Jura25 2010-12-05 16:52:03

1

Вы можете работать с логическими результатами, используя сумму или среднее значение, чтобы получить значимые итоговые результаты:

100* # to get percentages 
with(tradesList, 
tapply((TradeResult.Currency. > 0) , Instrument, sum)/ # number GT 0 
     tapply(TradeResult.Currency., Instrument, length)) # total number 

Edit: я заметил, что Гэвин дал вам ответ, возвращающей dataframe, в целом хорошо понятый класс. Класс значений из обоих ответов Габора и моих ответов был массивами одного измерения. Они могут быть превращены в именованные векторы, окружая объект c(), который удваивается как конкатенация и принуждение к векторной функции. И поскольку они стоят, они вполне приемлемы для перебора или доступа с помощью «[» в ожидаемых вариантах и ​​получения ожидаемых результатов от имен().

Функция tapply возвращает массивы с количеством измерений в аргументах INDEX и может быть очень эффективно объединена для матричных операций с объектами таблицы.Я делаю много деления сумм по счетам или подсчитывает суммы, чтобы получить значимую статистику категории в 2, 3 или 4 измерениях.

+0

Спасибо, DWin, nice clean suggest ион, даже понятный для начинающего, как я. Я предполагаю, что оператор with() - это то, что я буду чаще. Спасибо, что ответили! – Jura25 2010-12-05 16:58:18

2

Попробуйте это:

100 * tapply(tradesList$TradeResult.Currency. > 0, tradesList$Instrument, mean) 

с образцом данных в пост это дает:

JPM KFT 
66.67 20.00 

и здесь она с помощью sqldf (обратите внимание, что водитель RSQLite переводит точки подчеркивания, поскольку точки являются также оператор SQL, поэтому мы используем символы подчеркивания, где были точки):

> library(sqldf) 
> sqldf("select Instrument, 
+  100 * avg(TradeResult_Currency_ > 0) as '%>0', 
+  avg(TradeResult_Currency_) as 'Avg Currency' 
+  from tradesList group by Instrument") 
    Instrument %>0 Avg Currency 
1  JPM 66.67  100.5 
2  KFT 20.00  -57.4 

Эти два могут быть o будет переведено на aggregate подходящей модификацией уже принятого решения aggregate.

+0

Спасибо Г. Гротендик, простой и элегантный, но довольно эффективный. Спасибо, что ответили! – Jura25 2010-12-05 16:53:55

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