我想计算二元因子变量的变化次数。对于每个用户ID,此变量可以不时地多次来回更改。现在我想在给定的时间跨度内计算每个用户id对此变量的更改次数。
数据按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
答案 0 :(得分:5)
另一个编辑:
鉴于您对其他解决方案的回答,您可以在一行中得到您想要的内容:
Data$extra <- ave(as.integer(Data$myf),Data$id,FUN=function(x) sum(diff(x)!=0))
在这种情况下不需要合并。
“超过给定的时间跨度”意味着您可以选择一个时间跨度然后应用该功能。 Joshuas的答案是最快的方式。有一个更通用的函数可以为您提供有关运行长度和值rle
的更多信息。一定要检查一下。
根据Joshuas的回答,这个例子向您展示了如何轻松使用日期来选择给定的时间跨度。
编辑:我更新了答案,向您展示如何轻松地将年份和月份列转换为日期。在将整个事物应用于像你这样的因素时,你也应该使用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)
答案 1 :(得分:4)
#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 :(得分:2)
这是我的猜测。
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