R 基于两列的减法结果创建一个新列

R 基于两列的减法结果创建一个新列,r,R,我有两个这样的大型数据集: df1=data.frame(subject = c(rep(1, 12), rep(2, 10)), day =c(1,1,1,1,1,2,3,15,15,15,15,19,1,1,1,1,2,3,15,15,15,15),stime=c('4/16/2012 6:25','4/16/2012 7:01','4/16/2012 17:22','4/16/2012 17:45','4/16/2012 18:13','4/18/2012 6:50','4/19/2012

我有两个这样的大型数据集:

df1=data.frame(subject = c(rep(1, 12), rep(2, 10)), day =c(1,1,1,1,1,2,3,15,15,15,15,19,1,1,1,1,2,3,15,15,15,15),stime=c('4/16/2012 6:25','4/16/2012 7:01','4/16/2012 17:22','4/16/2012 17:45','4/16/2012 18:13','4/18/2012 6:50','4/19/2012 6:55','5/1/2012 6:28','5/1/2012 7:00','5/1/2012 16:28','5/1/2012 17:00','5/5/2012 17:00','4/23/2012 5:56','4/23/2012 6:30','4/23/2012 16:55','4/23/2012 17:20','4/25/2012 6:32','4/26/2012 6:28','5/8/2012 5:54','5/8/2012 6:30','5/8/2012 15:55','5/8/2012 16:30'))

df2=data.frame(subject = c(rep(1, 10), rep(2, 10)), day=c(1,1,2,2,3,3,9,9,15,15,1,1,2,2,3,3,9,9,15,15),dtime=c('4/16/2012 6:15','4/16/2012 15:16','4/18/2012 7:15','4/18/2012 21:45','4/19/2012 7:05','4/19/2012 23:17','4/28/2012 7:15','4/28/2012 21:12','5/1/2012 7:15','5/1/2012 15:15','4/23/2012 6:45','4/23/2012 16:45','4/25/2012 6:45','4/25/2012 21:30','4/26/2012 6:45','4/26/2012 22:00','5/2/2012 7:00','5/2/2012 22:00','5/8/2012 6:45','5/8/2012 15:45'))            

在df2中,“dtime”包含每个主题每天的两个时间点。我想使用df1中每天每个sub的时间点(即“stime”)减去df2中每天每个sub的第二个时间点,如果结果为正,则给出该观察的第二个时间点,否则给出第一个时间点。例如,对于第1天的主题1,('4/16/2012 6:25'-'4/16/2012 15:16')0, 因此,我们将第二个时间点'4/16/2012 15:16'赋予该obs。预期输出应如下所示:

df3=data.frame(subject = c(rep(1, 12), rep(2, 10)), day =c(1,1,1,1,1,2,3,15,15,15,15,19,1,1,1,1,2,3,15,15,15,15),stime=c('4/16/2012 6:25','4/16/2012 7:01','4/16/2012 17:22','4/16/2012 17:45','4/16/2012 18:13','4/18/2012 6:50','4/19/2012 6:55','5/1/2012 6:28','5/1/2012 7:00','5/1/2012 16:28','5/1/2012 17:00','5/5/2012 17:00','4/23/2012 5:56','4/23/2012 6:30','4/23/2012 16:55','4/23/2012 17:20','4/25/2012 6:32','4/26/2012 6:28','5/8/2012 5:54','5/8/2012 6:30','5/8/2012 15:55','5/8/2012 16:30'), dtime=c('4/16/2012 6:15','4/16/2012 6:15','4/16/2012 15:16','4/16/2012 15:16','4/16/2012 15:16','4/18/2012 7:15','4/19/2012 7:05','5/1/2012 7:15','5/1/2012 7:15','5/1/2012 15:15','5/1/2012 15:15','.','4/23/2012 6:45','4/23/2012 6:45','4/23/2012 16:45','4/23/2012 16:45','4/25/2012 6:45','4/26/2012 6:45','5/8/2012 6:45','5/8/2012 6:45','5/8/2012 15:45','5/8/2012 15:45'))

我使用下面的代码来实现这一点,但是,由于第19天缺少“dtime”,R不断给我错误:

df1$dtime <- apply(df1, 1, function(x){  
                  choices <- df2[ df2$subject==as.numeric(x["subject"]) & 
                                       df2$day==as.numeric(x["day"]) , "dtime"]
         if( as.POSIXct(x["stime"], format="%m/%d/%Y %H:%M") < 
                 as.POSIXct(choices[2],format="%m/%d/%Y %H:%M") ) {
            choices[1] 
            }else{ choices[2] } 
                                  } )

Error in if (as.POSIXct(x["stime"], format = "%m/%d/%Y %H:%M") < as.POSIXct(choices[2],  : missing value where TRUE/FALSE needed

df1$dtime首先,我输入了两个数据帧来进行测试。以下是我对伪代码方法的想法(将留给您完成代码)。输入时,df1如下所示:

   subject day           stime
1        1   1  4/16/2012 6:25
2        1   1  4/16/2012 7:01
3        1   1 4/16/2012 17:22
4        1   1 4/16/2012 17:45
5        1   1 4/16/2012 18:13
6        1   2  4/18/2012 6:50
7        1   3  4/19/2012 6:55
8        1  15   5/1/2012 6:28
9        1  15   5/1/2012 7:00
10       1  15  5/1/2012 16:28
11       1  15  5/1/2012 17:00
12       2   1  4/23/2012 5:56
13       2   1  4/23/2012 6:30
14       2   1 4/23/2012 16:55
15       2   1 4/23/2012 17:20
16       2   2  4/25/2012 6:32
17       2   3  4/26/2012 6:28
18       2  15   5/8/2012 5:54
19       2  15   5/8/2012 6:30
20       2  15  5/8/2012 15:55
21       2  15  5/8/2012 16:30
为什么不尝试以下方法:

   subject day           stime
1        1   1  4/16/2012 6:25
2        1   1  4/16/2012 7:01
3        1   1 4/16/2012 17:22
4        1   1 4/16/2012 17:45
5        1   1 4/16/2012 18:13
6        1   2  4/18/2012 6:50
7        1   3  4/19/2012 6:55
8        1  15   5/1/2012 6:28
9        1  15   5/1/2012 7:00
10       1  15  5/1/2012 16:28
11       1  15  5/1/2012 17:00
12       2   1  4/23/2012 5:56
13       2   1  4/23/2012 6:30
14       2   1 4/23/2012 16:55
15       2   1 4/23/2012 17:20
16       2   2  4/25/2012 6:32
17       2   3  4/26/2012 6:28
18       2  15   5/8/2012 5:54
19       2  15   5/8/2012 6:30
20       2  15  5/8/2012 15:55
21       2  15  5/8/2012 16:30
  • 首先,编写一个简单的循环,使您能够对df1和df2的stime列中的每个值进行循环。如果您愿意,可以将df1和df2数据帧转换为矩阵(使用as.matrix(),这是我的首选)

  • 从df1中获取第1行第3列中的第一个值(4/16/2012 6:25)后,拉出6:25并将其存储在临时变量中。。。我们把这个变量称为a

  • 对df2执行完全相同的操作,您也希望与之进行比较,并将其存储在临时变量中,只是从相关位置获取变量。。。我们把这个变量称为b

  • 减去两个临时变量(您可能需要编写一些代码来设置这两个部分,这样您就可以轻松地进行a-b运算并得到一个数字答案。也就是说,我将由您决定)

  • 使用简单的条件if语句检查答案是肯定的还是否定的

  • 根据条件检查的输出获取a或b的值

  • 将此新值添加到新数据表中,并带有适当的主题和日期。您已将其命名为df3


    • 我得到的答案与你的不同。首先,我制作了一份df1副本,用于:

      df4 <- df1
      df4$dtime <- apply(df4, 1, function(x){  
                            choices <- df2[ df2$subject==as.numeric(x["subject"]) & 
                                                 df2$day==as.numeric(x["day"]) , "dtime"]
                   if( as.POSIXct(x["stime"], format="%m/%d/%Y %H:%M") < 
                           as.POSIXct(choices[1],format="%m/%d/%Y %H:%M") ) {
                      choices[1] 
                      }else{ choices[2] } 
                                            } )
      #----------------------------------------------
         subject day           stime           dtime
      1        1   1  4/16/2012 6:25 4/16/2012 15:16
      2        1   1  4/16/2012 7:01 4/16/2012 15:16
      3        1   1 4/16/2012 17:22 4/16/2012 15:16
      4        1   1 4/16/2012 17:45 4/16/2012 15:16
      5        1   1 4/16/2012 18:13 4/16/2012 15:16
      6        1   2  4/18/2012 6:50  4/18/2012 7:15
      7        1   3  4/19/2012 6:55  4/19/2012 7:05
      8        1  15   5/1/2012 6:28   5/1/2012 7:15
      9        1  15   5/1/2012 7:00   5/1/2012 7:15
      10       1  15  5/1/2012 16:28  5/1/2012 15:15
      11       1  15  5/1/2012 17:00  5/1/2012 15:15
      12       2   1  4/23/2012 5:56  4/23/2012 6:45
      13       2   1  4/23/2012 6:30  4/23/2012 6:45
      14       2   1 4/23/2012 16:55 4/23/2012 16:45
      15       2   1 4/23/2012 17:20 4/23/2012 16:45
      16       2   2  4/25/2012 6:32  4/25/2012 6:45
      17       2   3  4/26/2012 6:28  4/26/2012 6:45
      18       2  15   5/8/2012 5:54   5/8/2012 6:45
      19       2  15   5/8/2012 6:30   5/8/2012 6:45
      20       2  15  5/8/2012 15:55  5/8/2012 15:45
      21       2  15  5/8/2012 16:30  5/8/2012 15:45
      

      df4您似乎不太清楚为哪些数据类型定义了减法运算。请参见
      ?Ops
      ,以提高您的抓球能力。抓得好。我应该澄清一下。我完全知道6:25的格式不允许简单的减法。也就是说,上面的解决方案仍然有效,这取决于您将格式设置为能够“区分”两个时间点的形式。我以前做过大规模的时间序列分析,这就是为什么我在回答中提到了以下几点:“您可能需要编写一些代码来设置这两个部分,以便您可以轻松地进行a-b运算并获得数字答案。也就是说,我将把这留给您。”您的代码工作正常,唯一使输出不同的是,我们应该在as.POSIXct()语句中使用选项[2]而不是选项[1]。但是,R在if(as.POSIXct(x[“SPI1O]”,format=“%m/%d/%Y%H:%m”)df1$stimethaks的代码进行提示回复!但是在将StringsFators设置为FALSE并将日期时间列转换为字符后,错误仍然存在。因此我删除了“stime”和“dtime”中缺少值的行,但错误没有消失。