如何有条件地计算R中行之间的列值差异?

如何有条件地计算R中行之间的列值差异?,r,R,我有以下数据集 (这只是一个示例,实际数据集按行运行) 中数据集的图像也附加在快照中 我需要为每个用户进行计算 每当发生“标志更改”时,行之间的时间差(以秒为单位),并将其存储在名为“时间差”的新列中 i、 e.每当标志从1变为2,或从2变为3,或从2变为1,或从3变为1时,我需要计算当前行和前一行之间的时间差,当遇到标志变化时 我有hh:mm:ss格式的时间。 有什么for循环函数可以在这里应用吗 感谢您的帮助。可能需要提前进行一些预处理: df$Time<-strptime(x

我有以下数据集

(这只是一个示例,实际数据集按行运行)

中数据集的图像也附加在快照中

我需要为每个用户进行计算

  • 每当发生“标志更改”时,行之间的时间差(以秒为单位),并将其存储在名为“时间差”的新列中

  • i、 e.每当标志从1变为2,或从2变为3,或从2变为1,或从3变为1时,我需要计算当前行和前一行之间的时间差,当遇到标志变化时

  • 我有hh:mm:ss格式的时间。 有什么for循环函数可以在这里应用吗


感谢您的帮助。

可能需要提前进行一些预处理:

df$Time<-strptime(x = df$Time,format = "%H:%M:%S")
df$Time<-strftime(x = df$Time,format = "%H:%M:%S")
df$Time<-as.POSIXct(df$Time)

sol<-function(d){
    Time_difference<-numeric(nrow(d))
    ind<-which(diff(d$Flag)!=0)+1

    #calculate differences in time where change in Flag was detected
    Time_difference[ind]<-abs(difftime(time1 = d$Time[ind],time2 = 
    d$Time[(ind-1)], units = "secs"))
    d$Time_Difference<-Time_difference
    return(d)
   }

一种方法是将时间变量转换为POSIXlt time对象,根据移位的时间变量计算时间差(所有行)。然后使用
标志
变量将
NA
设置为您不想要的。重要的是您需要区分
标志
变量,以便知道标志何时更改

我在这里列出了所有步骤,但可能有一种更快的方法:

# Create the data
flag <- c(1,1,1,2,1,1,1,1,3,2,1,1,1,1,1,1)
time <- c('11:39:30','11:37:53','20:44:19','22:58:42','23:01:54',
          '23:03:00','23:03:33','23:03:53','15:00:42','19:35:31',
          '19:35:34','10:19:06','10:59:50','10:59:50','12:16:36',
          '12:16:36')

# Shift the time
time_shift <- c(NA,time[1:length(time)-1])

# Turn into POSIXlt objects
time <- strptime(time, format='%H:%M:%S')
time_shift <- strptime(time_shift, format='%H:%M:%S')

data <- data.frame(time, time_shift, flag)

# Calculate diffs
data$time_diff <- as.numeric(abs(difftime(data$time, data$time_shift, units=('secs'))))
data$flag_diff <- c(NA,abs(diff(data$flag)))

# Set non 'flag change' diffs to NA
data$time_diff[data$flag_diff == 0] <- NA
这将导致一个如下所示的数据帧:

       time flag time_diff
1  11:39:30    1        NA
2  11:37:53    1        NA
3  20:44:19    1        NA
4  22:58:42    2      8063
5  23:01:54    1       192
6  23:03:00    1        NA
7  23:03:33    1        NA
8  23:03:53    1        NA
9  15:00:42    3     28991
10 19:35:31    2     16489
11 19:35:34    1         3
12 10:19:06    1        NA
13 10:59:50    1        NA
14 10:59:50    1        NA
15 12:16:36    1        NA
16 12:16:36    1        NA

我觉得你有些矛盾。对于A组,计算从
2-1
开始的差值。在B组中,您计算
1-3-2
..的差异(即为什么不为B组计算
1-3-2-1
,或者为A计算
1-2-1
)。实际上..对于A组,当它从1到2时,它将计算差异并存储它对应于2,当它从2到1时,它将存储它对应于1,也就是说,从1到2和从2到1计算两次差值。类似地,在B组中,其从1-3-2-1转换发生3次,因此时间差将计算3次。。可以存储与转换值相对应的差异。Ok。请您也添加预期的输出。这将进一步澄清more@Sotos我已经更新了预期输出供您参考。谢谢。谢谢。我会尝试一下。实际上,我只是为了代表起见才放了这个样本。实际上,我有另一个数据集,它的标志是alaphanumeric…即,它的2A不是2,3是3A,1是1A。。我可以用muneric替换字母数字,然后试试你的解决方案……但是让我们看看我是否能找到一个像你建议的那样快速的方法。是的,你不能用字母数字来做区分。但是,如果字母不重要,你可以把它们去掉,然后继续数字。下次,在问题中加入字母数字问题,因为这会发生很大变化。总的来说,至少这比使用
for
循环要快
# Create the data
flag <- c(1,1,1,2,1,1,1,1,3,2,1,1,1,1,1,1)
time <- c('11:39:30','11:37:53','20:44:19','22:58:42','23:01:54',
          '23:03:00','23:03:33','23:03:53','15:00:42','19:35:31',
          '19:35:34','10:19:06','10:59:50','10:59:50','12:16:36',
          '12:16:36')

# Shift the time
time_shift <- c(NA,time[1:length(time)-1])

# Turn into POSIXlt objects
time <- strptime(time, format='%H:%M:%S')
time_shift <- strptime(time_shift, format='%H:%M:%S')

data <- data.frame(time, time_shift, flag)

# Calculate diffs
data$time_diff <- as.numeric(abs(difftime(data$time, data$time_shift, units=('secs'))))
data$flag_diff <- c(NA,abs(diff(data$flag)))

# Set non 'flag change' diffs to NA
data$time_diff[data$flag_diff == 0] <- NA
data$time <- format(data$time, "%H:%M:%S")
data <- data[c('time', 'flag', 'time_diff')]
       time flag time_diff
1  11:39:30    1        NA
2  11:37:53    1        NA
3  20:44:19    1        NA
4  22:58:42    2      8063
5  23:01:54    1       192
6  23:03:00    1        NA
7  23:03:33    1        NA
8  23:03:53    1        NA
9  15:00:42    3     28991
10 19:35:31    2     16489
11 19:35:34    1         3
12 10:19:06    1        NA
13 10:59:50    1        NA
14 10:59:50    1        NA
15 12:16:36    1        NA
16 12:16:36    1        NA