在数据框中创建新列,该列开始从第三列指定的行开始添加列中的值

时间:2014-03-18 18:48:46

标签: r dataframe multiple-conditions

我正在尝试确定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_

1 个答案:

答案 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