#r #dataframe
#r #фрейм данных
Вопрос:
Это мои данные:
> head(Kandula_for_n)
date dist date_only
1 2005-05-08 12:00:00 138.5861 2005-05-08
2 2005-05-08 16:00:00 1166.9265 2005-05-08
3 2005-05-08 20:00:00 1270.7149 2005-05-08
6 2005-05-09 08:00:00 233.1971 2005-05-09
7 2005-05-09 12:00:00 1899.9530 2005-05-09
8 2005-05-09 16:00:00 726.8363 2005-05-09
Теперь я хотел бы иметь дополнительный столбец с количеством (n) записей данных (dist) в день. Для 2005-05-08 это будет n = 3, так как есть 3 записи данных в 12, 16 и 20 часов. Я применил следующий код, который на самом деле дал мне то, что я хотел:
ndist <-tapply(1:NROW(Kandula_for_n), Kandula_for_n$date_only, function(x) length(unique(x)))
После ndist<-as.data.frame(ndist)
того , как я получил это:
> head(ndist)
ndist
2005-05-08 3
2005-05-09 4
2005-05-10 6
2005-05-11 4
2005-05-12 6
2005-05-13 6
Проблема в том, что счетчик находится вместе с date_only в одном столбце, который называется ndist. Но мне они понадобились бы в двух отдельных столбцах, один с count и один с date_only . Как это можно сделать?
Я думаю, это довольно просто, но я просто не понимаю.
Я был бы признателен, если бы вы могли высказать мне какие-либо соображения по этому поводу.
Спасибо за ваши усилия.
Ответ №1:
Просто потому tapply()
, что мне трудно обернуть свой мозг, мне нравится использовать plyr
для таких вещей:
## make up some data
## you get better/faster/more answers if you do this bit for us :)
dates <- seq(Sys.Date(), Sys.Date() 5, by = 1)
Kandula_for_n <- data.frame(date_only = sample( dates 5, 10, replace=TRUE ) , dist=rnorm(10) )
require(plyr)
ddply(Kandula_for_n, "date_only", function(x) data.frame(x, ndist=nrow(x)) )
Это даст вам что-то вроде:
date_only dist ndist
1 2011-10-30 0.2434168 5
2 2011-10-30 -0.9361780 5
3 2011-10-30 1.4593197 5
4 2011-10-30 -0.1851402 5
5 2011-10-30 0.6652419 5
6 2011-10-31 0.8876420 1
7 2011-11-03 0.5087175 2
8 2011-11-03 -1.0065152 2
9 2011-11-04 0.4236352 2
10 2011-11-04 0.4535686 2
строка ddply
:
ddply(Kandula_for_n, "date_only", function(x) data.frame(x, ndist=nrow(x)) )
принимает входные данные, группирует их по date.only
полю и для каждого уникального значения применяет анонимную функцию к фрейму данных, состоящему только из записей с одинаковым значением для date_only
. Моя анонимная функция просто берет data.frame x
и добавляет столбец с именем ndist
, которое соответствует количеству строк в x
нем.
Комментарии:
1. Спасибо вам за ваше предложение. Я уже несколько раз спотыкался о плир. Я думаю, что обязательно немного разберусь в этом. И с этого момента я обязательно постараюсь собрать эти данные…
Ответ №2:
Это всего лишь имена строк. Все готово:
ndist$date = row.names(ndist)
РЕДАКТИРОВАТЬ: или ndist = data.frame(date = names(ndist), ndist)
в зависимости от того, является ли это уже фреймом данных или нет.
Комментарии:
1. или
data.frame(ndist,date_only=names(ndist),row.names=1:length(ndist))
2. или просто оставьте переменные идентификатора в качестве атрибутов имен (строк) и просто индексируйте напрямую, когда это необходимо. Это то, что я обычно делаю.
3. Спасибо, меня действительно смутили эти странные названия строк.
Ответ №3:
Как насчет чего-то более простого:
as.data.frame(table(unique(Kandula_for_n)$date_only))
Комментарии:
1. это действительно очень просто. спасибо за это. Приятно знать этот фрагмент.