Сообщение об отсутствующих значениях для каждой подгруппы в R из фрейма данных

У меня есть фрейм данных, похожий на приведенный ниже.

Group Expenditure Date
A     56434       22 June 2014
B     54231       1 July 2013
B     1412        9 May 2011
A     NA           28 July 2009
A     NA           3 July 2009
C     98          2 July 1999
C     NA           14 July 2004

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

sapply(exp.dta, function(x) sum(is.na(x)))

Кроме того, я хотел бы сообщить количество пропущенных значений для каждой даты. Столбец даты форматируется как правильная дата с использованием функции as.Date. На данный момент я не заинтересован в сообщении пропущенных значений для каждой подгруппы.


person Konrad    schedule 17.07.2014    source источник
comment
Привет, Хенрик, спасибо за проявленный интерес. Данные импортируются из файла CSV, где отсутствующие данные о расходах кодируются как NA.   -  person Konrad    schedule 17.07.2014


Ответы (3)


Следуя коду, который вы уже написали, вы можете добавить к нему split,

dat <- read.table(h=T, text = "Group Expenditure Date
  A     56434       22-June-2014
  B     54231       1-July-2013
  B     1412        9-May-2011
  A     NA           28-July-2009
  A     NA           3-July-2009
  C     98          2-July-1999
  C     NA           14-July-2004")

> sapply(split(dat$Expenditure, dat$Group), function(x) sum(is.na(x)))
# A B C 
# 2 0 1 

или для каждой даты,

> s <- split(dat$Expenditure, dat$Date)
> as.matrix(sapply(s, function(x) sum(is.na(x))))
#              [,1]
# 14-July-2004    1
# 1-July-2013     0
# 22-June-2014    0
# 28-July-2009    1
# 2-July-1999     0
# 3-July-2009     1
# 9-May-2011      0
person Rich Scriven    schedule 17.07.2014

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

 library(plyr)
 ddply(your.data, .(Date), summarize, nNA = sum(is.na(Expenditure))

Это разбивает данные на подгруппы по Date и применяет функцию sum(is.na()) к столбцу Expenditure для этих подгрупп.

Например,

 df <- read.table(text="Group Expenditure Date
 A     56434       22June2014
 B     54231       1July2013
 B     1412        9May2011
 A     NA           28July2009
 A     NA           3July2009
 C     98          2July1999
 C     NA           14July2004 ", sep="", header=T)

 ddply(df, .(Date), summarize, nNA=sum(is.na(Expenditure)))

дает:

         Date nNA
 1 14July2004   1
 2  1July2013   0
 3 22June2014   0
 4 28July2009   1
 5  2July1999   0
 6  3July2009   1
 7   9May2011   0

Есть также несколько base-решений. Вот несколько примеров:

  • Использование by

    by(df, df$Date, function(x) sum(is.na(x$Expenditure)))
    
  • Использование tapply

    with(df, tapply(Expenditure, Date, function(x) sum(is.na(x))))
    
  • Использование aggregate (подсказка @user20650)

    aggregate(df$Expenditure, by=list(df$Date), FUN= function(x) sum(is.na(x)))
    

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

person coffeinjunky    schedule 17.07.2014
comment
Ваша ссылка на стратегию «разделить-применить-объединить» («Стратегия разделения-применения-объединения для анализа данных» Хэдли Уикхема) действительно полезна. Для тех, кто спотыкается в сети, с data.tableможет быть также полезно: brodieg.com/?p=7 - person Konstantinos; 25.01.2016

Или, используя dplyr:

library('dplyr')
summarize(group_by(df, Date), nNA = sum(is.na(Expenditure)))
person Kara Woo    schedule 17.07.2014