我经常在R中进行基本操作,因为我必须控制唯一标识符。
我大部分时间都使用“长格式”数据。
dt <- data.frame(id = c(rep("A1", 3), rep("B1", 3)),
activity = c(15,17,12,3,4,15),
begin = c( 0, 0, 1, 0, 1, 2 ) )
例如,按标识符计算时间或观察
dt$time <- 1
for(i in 2:nrow(dt)){
if(dt[i,'id'] == dt[i-1, 'id'])
{
dt[i,'time'] <- dt[i-1,'time'] + 1
}
}
或仔细检查重复数据
dt$zerocheck = 0
for(i in 2:nrow(dt)){
if( dt[i,'id'] == dt[i-1, 'id'] &
dt[i,'begin'] == dt[i-1, 'begin'] )
{
dt$zerocheck[i] <- 1
}
}
我猜答案会像id一样聚合,但我不完全确定。
merge(dt, aggregate(time ~ id, dt, "max"), by=c("id"), all.X=T)
为避免做循环,有什么建议吗?
答案 0 :(得分:4)
使用data.table
:
require(data.table)
setDT(dt)[, `:=`(time = seq_len(.N), zerocheck = begin == shift(begin)), by = id]
答案 1 :(得分:1)
要添加到其他示例,您还可以使用dplyr
library(dplyr)
dt %>% group_by(id) %>%
mutate(time = row_number()) %>% # creates the control for identifier
mutate(zerocheck= ifelse(begin==lag(begin), 1, 0)) # checks for repeated data
或者等效地你可以使用如下的单个mutate函数:
dt %>%
group_by(id) %>%
mutate(time = row_number(),
zerocheck=begin==lag(begin))
第一个查询有输出:
Source: local data frame [6 x 5]
Groups: id
id activity begin time zerocheck
1 A1 15 0 1 NA
2 A1 17 0 2 1
3 A1 12 1 3 0
4 B1 3 0 1 NA
5 B1 4 1 2 0
6 B1 15 2 3 0
对于zerocheck
情况,我只使用滞后来检查先前的值是否与当前值相同。这模仿了你问题中的代码。当然,如果你想检查别的东西,你可以很容易地改变谓词。