Условный Счет изменений со временем? - PullRequest
3 голосов
/ 25 октября 2010

Я бы хотел посчитать количество изменений двоичной переменной фактора.Эта переменная может время от времени меняться взад и вперед несколько раз для каждого идентификатора пользователя.Теперь я хотел бы посчитать количество изменений на один идентификатор пользователя для этой переменной за заданный промежуток времени.

Данные отсортированы по id, году, месяцу, myfactor.Я пробовал это в MySQL, но пока безуспешно.Есть ли простой способ сделать это в R?Я думал о добавлении еще одного столбца в мой data.frame и о пошаговом добавлении условий ... Может быть,%% в% материала?

Заранее спасибо за предложения ...

Хммконечно ... вот несколько примеров - извините, что не предоставил это немедленно, у меня болит голова;):


   myf   Year    month userid   
  1 A    2005       1    260           
  2 B    2005       2    260           
  3 B    2005       4    260           
  4 A    2005       5    260           
  5 B    2005       6    260           
  6 B    2005       1    261 

если это мой набор данных, я хочу обновить столбец изменений,подсчет количества изменений myf на пользователя.В основном я хотел бы в конечном итоге:

  user  changes
   260     3
   260     0

и так далее ...

HTH

Ответы [ 3 ]

5 голосов
/ 25 октября 2010

Другое изменение:

Учитывая ваши ответы на другие решения, вы можете получить то, что вы хотите в одной строке:

Data$extra <- ave(as.integer(Data$myf),Data$id,FUN=function(x) sum(diff(x)!=0))

В этом случае объединение не требуется.


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

На основе ответа Джошуаса этот пример показывает, как вы можете легко работать с датами для выбора заданного промежутка времени.

Редактировать: я обновил ответ напокажет вам, как легко конвертировать ваши столбцы год и месяц в дату.Вам также следует использовать as.numeric при применении всего этого к фактору, подобному вашему.

#Testdata
set.seed(21)
Data <- data.frame(id=rep(letters[1:3],each=24),
                   year= rep(rep(c(2005,2006),each=12),6),
                   month=rep(1:12,6),
                   myf=sample(c("A","B"),24*3,TRUE))

#transformation
Data$dates <- as.Date(paste(Data$year,Data$month,"1",sep="-"))
#function

cond.count <- function(from,to,data){
    x <- data[data$dates>from & data$dates<to,]
    tapply(as.numeric(x$myf),x$id,function(y)sum(diff(y)!=0))
}

#example
from <- as.Date("2005-01-01")
to <- as.Date("2006-04-15")

cond.count(from,to,Data)
4 голосов
/ 25 октября 2010
#Some data
dfr <- data.frame(
   binary_variable = runif(100) < .7,
   id = sample(7, 100, replace = TRUE)
)

#Split by id
split_by_id <- with(dfr, split(binary_variable, id))

#Number of changes
sapply(split_by_id, function(x) sum(diff(x) != 0))
2 голосов
/ 25 октября 2010

Вот мое предположение.

set.seed(21)
Data <- data.frame(id=sample(letters[1:3],20,TRUE),
                   date=sample(1:3,20,TRUE),
                   myfactor=sample(0:1,20,TRUE))
Data <- Data[order(Data$id,Data$date),]

DataCh <- aggregate(Data[,"myfactor",FALSE],
            by=Data[,c("id","date")], function(x) sum(diff(x)!=0))
DataCh <- DataCh[order(DataCh$id,DataCh$date),]

РЕДАКТИРОВАТЬ: Вот обновление с вашими примерами данных.

lines <- "   myf   Year    month userid   
 1 A    2005       1    260           
 2 B    2005       2    260           
 3 B    2005       4    260           
 4 A    2005       5    260           
 5 B    2005       6    260           
 6 B    2005       1    261 "

Data <- read.table(con <- textConnection(lines)); close(con)

DataCh <- aggregate(Data[,"myf",FALSE],
            by=Data[,"userid",FALSE], function(x) sum(diff(unclass(x))!=0))

merge(Data,DataCh,by="userid",suffixes=c("",".change"))
#   userid myf Year month myf.change
# 1    260   A 2005     1          3
# 2    260   B 2005     2          3
# 3    260   B 2005     4          3
# 4    260   A 2005     5          3
# 5    260   B 2005     6          3
# 6    261   B 2005     1          0
...