NullPointerException
s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException
. Они наиболее распространены, но другие способы перечислены на странице NullPointerException
javadoc.
Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException
, be:
public class Example {
public static void main(String[] args) {
Object obj = null;
obj.hashCode();
}
}
В первой строке внутри main
я явно устанавливаю ссылку Object
obj
равной null
. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException
, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.
(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)
Используя aggregate
:
aggregate(x$Frequency, by=list(Category=x$Category), FUN=sum)
Category x
1 First 30
2 Second 5
3 Third 34
(вложение комментария @thelatemail), aggregate
также имеет интерфейс формулы
aggregate(Frequency ~ Category, x, sum)
Или, если вы хотите для объединения нескольких столбцов вы можете использовать нотацию .
(работает для одного столбца тоже)
aggregate(. ~ Category, x, sum)
или tapply
:
tapply(x$Frequency, x$Category, FUN=sum)
First Second Third
30 5 34
Используя эти данные:
x <- data.frame(Category=factor(c("First", "First", "First", "Second",
"Third", "Third", "Second")),
Frequency=c(10,15,5,2,14,20,3))
Ответ, предоставленный rcs, работает и прост. Однако, если вы работаете с большими наборами данных и нуждаетесь в повышении производительности, существует более быстрая альтернатива:
library(data.table)
data = data.table(Category=c("First","First","First","Second","Third", "Third", "Second"),
Frequency=c(10,15,5,2,14,20,3))
data[, sum(Frequency), by = Category]
# Category V1
# 1: First 30
# 2: Second 5
# 3: Third 34
system.time(data[, sum(Frequency), by = Category] )
# user system elapsed
# 0.008 0.001 0.009
Давайте сравним это с тем же, используя data.frame и выше:
data = data.frame(Category=c("First","First","First","Second","Third", "Third", "Second"),
Frequency=c(10,15,5,2,14,20,3))
system.time(aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum))
# user system elapsed
# 0.008 0.000 0.015
И если вы хотите сохранить столбец, это синтаксис:
data[,list(Frequency=sum(Frequency)),by=Category]
# Category Frequency
# 1: First 30
# 2: Second 5
# 3: Third 34
Разница станет более заметной с более крупными наборами данных, как показывает следующий код:
data = data.table(Category=rep(c("First", "Second", "Third"), 100000),
Frequency=rnorm(100000))
system.time( data[,sum(Frequency),by=Category] )
# user system elapsed
# 0.055 0.004 0.059
data = data.frame(Category=rep(c("First", "Second", "Third"), 100000),
Frequency=rnorm(100000))
system.time( aggregate(data$Frequency, by=list(Category=data$Category), FUN=sum) )
# user system elapsed
# 0.287 0.010 0.296
Для множественных агрегаций вы можете комбинировать lapply
и .SD
следующим образом
data[, lapply(.SD, sum), by = Category]
# Category Frequency
# 1: First 30
# 2: Second 5
# 3: Third 34
data[, sum(Frequency), by = Category]
. Вы можете использовать .N
, который заменяет функцию sum()
. data[, .N, by = Category]
. Вот полезная таблица: s3.amazonaws.com/assets.datacamp.com/img/blog/…
– Stophface
22 February 2017 в 12:47
Это несколько , связанное с этим вопросом .
Вы также можете просто использовать функцию by () :
x2 <- by(x$Frequency, x$Category, sum)
do.call(rbind,as.list(x2))
Эти другие пакеты (plyr, reshape) имеют преимущество в возврате данных .frame, но это стоит знать с помощью (), поскольку это базовая функция.
Просто добавьте третий вариант:
require(doBy)
summaryBy(Frequency~Category, data=yourdataframe, FUN=sum)
EDIT: это очень старый ответ. Теперь я бы рекомендовал использовать group_by и суммировать из dplyr, как в ответе @docendo.
Несколько лет спустя просто добавить еще одно простое базовое R-решение, которое по какой-то причине отсутствует здесь xtabs
xtabs(Frequency ~ Category, df)
# Category
# First Second Third
# 30 5 34
Или, если хотите data.frame
назад
as.data.frame(xtabs(Frequency ~ Category, df))
# Category Freq
# 1 First 30
# 2 Second 5
# 3 Third 34
Совсем недавно вы также можете использовать пакет dplyr для этой цели:
library(dplyr)
x %>%
group_by(Category) %>%
summarise(Frequency = sum(Frequency))
#Source: local data frame [3 x 2]
#
# Category Frequency
#1 First 30
#2 Second 5
#3 Third 34
Или для нескольких суммарных столбцов (работает с одним столбцом тоже):
x %>%
group_by(Category) %>%
summarise_each(funs(sum))
Обновление для dplyr> = 0.5: summarise_each
было заменено на семейство функций summarise_all
, summarise_at
и summarise_if
в dplyr.
Или, если у вас есть несколько столбцов для группировки, вы можете указать все из них в group_by
, разделенные запятыми:
mtcars %>%
group_by(cyl, gear) %>% # multiple group columns
summarise(max_hp = max(hp), mean_mpg = mean(mpg)) # multiple summary columns
Для получения дополнительной информации, включая оператор %>%
, см. введение в dplyr .
, используя cast
вместо recast
(примечание 'Frequency'
теперь 'value'
)
df <- data.frame(Category = c("First","First","First","Second","Third","Third","Second")
, value = c(10,15,5,2,14,20,3))
install.packages("reshape")
result<-cast(df, Category ~ . ,fun.aggregate=sum)
, чтобы получить:
Category (all)
First 30
Second 5
Third 34
Хотя я недавно стал конвертером в dplyr
для большинства этих типов операций, пакет sqldf
по-прежнему очень хорош (и IMHO более читабельным) для некоторых вещей.
Вот пример того, как можно ответить на этот вопрос с помощью sqldf
x <- data.frame(Category=factor(c("First", "First", "First", "Second",
"Third", "Third", "Second")),
Frequency=c(10,15,5,2,14,20,3))
sqldf("select
Category
,sum(Frequency) as Frequency
from x
group by
Category")
## Category Frequency
## 1 First 30
## 2 Second 5
## 3 Third 34
library(plyr)
ddply(tbl, .(Category), summarise, sum = sum(Frequency))
Если x
- это кадр данных с вашими данными, то следующее будет делать то, что вы хотите:
require(reshape)
recast(x, Category ~ ., fun.aggregate=sum)