我正在尝试确定data.frame中变量的延迟,该数据包含多个位置,其中相关数据列在一系列“开始”之间。并且'停止'标记。
为了实现这一目标,我需要创建一个新列,在每次试验开始时从0开始计数,并以毫秒为单位计算,直到试验停止或下一次试验开始(以较为容易的为准,我假设后者。)
我有这个:
df <- data.frame(c(0, 32, 32, 32, 32, 31, 31, 29), c(0, 32, 64, 96, 128, 159, 190, 219), c("Start", NA_character_, NA_character_, "Stop", NA_character_, NA_character_, "Start", NA_character_))
colnames(df) <- c('Delta', 'TimeMs', 'Marker')
我想做到这一点:
df <- data.frame(c(0, 32, 32, 32, 32, 31, 31, 29), c(0, 32, 64, 96, 128, 159, 190, 119), c("Start", NA_character_, NA_character_, "Stop", NA_character_, NA_character_, "Start", NA_character_), c(0, 32, 64, 96, 128, 159, 190, 0))
colnames(df) <- c('Delta', 'TimeMs', 'Marker', 'Latency')
显然,我会在新列中填充自动生成的NA:
df$Latency <- NA
然后我想我会在Stat列位所在的新列0中标记:
df$Latency [which(df$Marker == 'Start')] <- 0
从那里我被卡住了。我以为我可以以某种方式使用which命令,但是我的基本R技能让我相信这种方法已经过度简化而且不正确。
提前感谢您的帮助,请询问您是否需要澄清!
编辑:修复示例,标题
edit2:修复示例
edit3:使用了真实NA_character_
答案 0 :(得分:1)
这似乎有效
df <- data.frame(Delta=c(0, 32, 32, 32, 32, 31, 31, 29),
TimeMS=c(0, 32, 64, 96, 128, 159, 190, 219),
Marker=c("Start", "NA", "NA", "Stop", "NA", "NA", "Start", "NA"))
df$group <- cumsum(df$Marker=="Start" & !is.na(df$Marker))
df$Latency <- unlist(aggregate(TimeMS~group,df,function(x)cumsum(c(0,diff(x))))$TimeMS)
df[,"group"] <- NULL
df
# Delta TimeMS Marker Latency
# 1 0 0 Start 0
# 2 32 32 NA 32
# 3 32 64 NA 64
# 4 32 96 Stop 96
# 5 32 128 NA 128
# 6 31 159 NA 159
# 7 31 190 Start 0
# 8 29 219 NA 29
首先,我们添加一列df$group
,每次df$Marker=="Start"
递增1(因此,{1}表示行1:6,= 2表示行7:8)。然后,我们使用df$group=1
函数按组聚合TimeMS
。应用于长度为n的向量,diff(...)
返回长度为n-1的向量,该向量包含给定行与前一行之间的差异。所以我们需要在这个向量的开头插入一个0。 diff(...)
会返回两组向量(一组用于aggregate(...)
,另一组用于group==1
),因此我们需要在绑定到group==2
之前unlist(...)
成一个向量。最后一行只删除df