разбить xts-dataframe на несколько групп, свернуть в недельные данные и сохранить индекс времени - PullRequest
1 голос
/ 25 января 2012

Я новичок в R, поэтому прошу прощения, если ответ на мой вопрос слишком очевиден.Я набор данных в следующей форме:

Date, V1,V...,VN,Land,Nace
22/03/1995 23:01:12,1,3,2,15,A
21/03/1995 21:01:12,3,3,1,9,C
1/04/1995 17:01:06,3,2,1,3,B   

Я хотел бы проанализировать данные в data.frame по земле, NACE (это отраслевой код), Дата (я хотел бы свернуть всеподумайте о еженедельных данных) и тремя различными вариантами ответа {1,2,3} в V1 ... VN.Это образец моих данных:

example <- as.data.frame(structure(c(" 1", " 2", " 1", " 2", " 1", " 1", " 2", " 1", " 2", 
" 1", " 2", " 3", " 1", " 1", " 2", " 2", " 3", " 1", " 2", " 2", 
" 1", " 2", " 1", " 1", " 2", NA, " 2", NA, NA, " 1", " 3", " 1", 
" 3", " 3", " 2", " 3", " 3", " 3", " 2", " 2", " 2", " 3", " 3", 
" 3", " 2", " 2", " 3", " 3", " 3", " 3", " 1", " 2", " 1", " 2", 
" 2", " 1", " 2", " 1", " 2", " 2", " 2", " 3", " 1", " 1", " 2", 
" 2", " 3", " 3", " 2", " 2", " 1", " 2", " 1", " 1", " 2", NA, 
" 2", NA, NA, " 1", " 3", " 2", " 3", " 2", " 0", " 3", " 3", 
" 3", " 2", " 0", " 2", " 3", " 3", " 3", " 0", " 2", " 2", " 3", 
" 3", " 0", "12", " 5", " 9", "14", " 5", "tra", "tra", "man", 
"inf", "agc", "07-2011", "07-2011", "07-2011", "07-2011", "07-2011" 
), .indexCLASS = c("POSIXlt", "POSIXt"), .indexTZ = "", class = c("xts", 
"zoo"), .indexFORMAT = "%U-%Y", index = structure(c(1297642226, 
1297672737, 1297741204, 1297748893, 1297749513), tzone = "", tclass = c("POSIXlt", 
"POSIXt")), .Dim = c(5L, 23L), .Dimnames = list(NULL, c("rev_sit", 
"prof_sit", "emp_nr_sit", "inv_sit", "ord_home_sit", "ord_abr_sit", 
"emp_cost_sit", "usage_cost_sit", "tax_cost_sit", "gov_cost_sit", 
"rev_exp", "prof_exp", "emp_nr_exp", "inv_exp", "ord_home_exp", 
"ord_abr_exp", "emp_cost_exp", "usage_cost_exp", "tax_cost_exp", 
"gov_cost_exp", "land", "nace", "index")))) 

prof_sit и т. Д. Являются вопросами, а ниже приведены ответы по шкале 1,2,3.land, nace и index (это временной индекс) - переменные, с помощью которых я хотел бы разделить набор данных.Цель состоит в том, чтобы получить фрейм данных xts, который бы выглядел следующим образом:

-,nace.land,nace.land,nace.land,...
10-1995,sum of answers coded i.e. as 1 for a certain nace and a certain land,sum,sum,...  
11-1995,sum,sum,...
12-1995,sum,sum,...

, где 12-1995 - 12-я календарная неделя в 1995 году. Ближайшее, что я пришел к этому решению, было с tapply:

pos <- as.data.frame(tapply((example[,1]==3)*1,
  list(example$index, example$land, example$nace), sum)) 

Это делает более или менее то, что я хочу от спада, что формат как объект xts потерян и, следовательно, строки не в правильном порядке.В качестве второго недостатка можно также упомянуть, что я собираюсь запустить циклы, чтобы применить ту же технику ко всем двадцати вопросам.Кто-нибудь знает решение этой проблемы?Я ценю любую помощь или подсказку, так как трачу свое время на эту проблему уже несколько дней.

С наилучшими пожеланиями,

andreas

Ответы [ 2 ]

2 голосов
/ 26 января 2012

Во-первых, помните, что объект xts - это матрица внизу, а не фрейм данных.Это означает, что все числовые или все символы.В вашем случае вам следует преобразовать код "Nace" в число.

Вот некоторые абстрактные тестовые данные:

library(xts)
x=xts(data.frame(value=1:100,code=rep(1:5,20)),seq(as.Date('2011-01-01'),by=1,length.out=100))

Упрощенная функция - это не то, что вам нужно:

apply.weekly(x,sum)
#           [,1]
#2011-01-03   12
#2011-01-10   73
#...

Обе колонки суммированы вместе!Таким образом, при работе с несколькими столбцами вы хотите:

apply.weekly(x,function(d){c(sum(d$value),sum(d$code))})
#           value code
#2011-01-03     6    6
#2011-01-10    49   24
#2011-01-17    98   18
#...

Вы можете получить в функции столько сложностей, сколько захотите, и можете вводить новые столбцы, например

apply.weekly(x,function(d){
  c(sum_value = sum(d$value),
   mean_value = mean(d$value),
        A_cnt = sum(d$code==1),
        B_cnt = sum(d$code==2)
   )
  })
#           sum_value mean_value A_cnt B_cnt
#2011-01-03         6        2.0     1     1
#2011-01-10        49        7.0     1     1
#2011-01-17        98       14.0     2     2
#...

Как насчет того,Вы хотите сделать дальнейшую группировку?В этом примере показано, как суммировать значения, сгруппированные по неделям, а затем сгруппированные по типу:

apply.weekly(x,function(d){
  t=tapply(d$value,d$code,sum)
  c(A=t[1],B=t[2],C=t[3],D=t[4],E=t[5])
  })
#           A.1 B.2 C.3 D.NA E.NA
#2011-01-03   1   2   3   NA   NA
#2011-01-10   6   7   8   13   15
#2011-01-17  27  29  13   14   15
#...
#2011-04-10  96  97  98   99  195

Извините: я воспользовался этой возможностью, чтобы пометить столбцы.Реальная причина: я не могу понять, как вернуть возвращаемое значение tapply так, как нравится XTS apply.weekly().Я попытался упростить = F, и unlist (t), as.vector (t), as.matrix (t), каждый с / без обертки ac ().Если / когда я это решу, я обновлю этот ответ.

Чтобы понять, что вы можете сделать в обратном вызове apply.weekly (), вы можете использовать команды печати. ​​

apply.weekly(x,function(d){
  print(d);str(d)
  })

Он жалуется, потому что мы не возвращаем что-то полезное, но это хорошо для интерактивной разработки.d является объектом XTS.Вы можете превратить его в data.frame с помощью df=as.data.frame(d).

0 голосов
/ 03 февраля 2012

большое спасибо за вашу помощь. Тем временем я был занят другими делами, но теперь я снова работал над своей проблемой, и с помощью ваших замечательных комментариев я нашел решение:

Я прекратил работать непосредственно с временными рядами, отложив этот шаг до конца моего анализа. Поэтому я беру вектор даты и преобразую его в недели:

библиотека (ISOweek)

d$index <- ISOweek(d$date)

(я делаю это с ISOweek, поскольку я использую Windows)

тогда я использую комбинацию tapply и lapply. Следующая функция вычисляет количество положительных ответов в опросе (с кодом 1) для каждой календарной недели (d$index = t[[22]]) и каждой комбинации двух категориальных столбцов t[[21]], t[[22]]. На этом же этапе все превращается в фрейм данных:

groupweeksums <- function(x,t){as.data.frame(tapply((x==1)*1,list(t[[23]],t[[21]],t[[22]]), function(d)sum(d,na.rm=TRUE)))}
  • x обозначает конкретный столбец,
  • t для фрейма данных (я не знал, как это сделать иначе, потому что в один момент мне нужно было обратиться к столбцу, а в другом - к фрейму данных, и я хотел избежать много печатания);

если d является фреймом данных, то:

df <- groupweeksums(d,d)

Чтобы мне не пришлось повторять эту процедуру для всех моих 20 вопросов, используйте lapply:

df <- as.data.frame(lapply(df[,1:20],function(d)groupweeksums(d,euwifo)))

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

P.S. Я также опубликую этот ответ на другой вопрос, который я разместил в stackoverflow, который был связан с этим первым.

...