2017-08-03 52 views
1

我包含三个变量,其中包含三个唯一ID,每个都有多个记录。见下面在R中创建一个新列,其中包含一些规则

ID <- c(rep(1,7), rep(2,6), rep(3,5)) 
t <- c(seq(1,7), seq(1,6), seq(1,5)) 
y <- c(rep(6,7), rep(1,6), rep(6,5)) 
z <- c(5,0,0,0,1,0,0,0,0,1,0,0,0,4,2,1,0,1) 
dat1 <- data.frame(ID, t, y, z) 

我需要创建一个新列(我们称之为updated_y0)以下规则:每个ID i = 1,2,3和每个记录j中,

  1. updated_y0(i,1)(即,按t排序的每个ID的第一条记录)= y(i,1)。

  2. updated_y0(i,j)其中j> 1(即从第二记录开始)= updated_y0(i,j-1)-z(i,j-1)(前面的行的差异)

例如,对于ID = 1,

  • updated_y0(1,1)= Y(1,1)= 6,

  • updated_y0(1,2)= updated_y0 (1,1)-z(1,1)= 6-5 = 1,

  • updated_y0(1,3)= updated_y0(1,2) - Z(1,2)= 1-0 = 1 ...

新的数据(DAT2)是

ID <- c(rep(1,7), rep(2,6), rep(3,5)) 
    t <- c(seq(1,7), seq(1,6), seq(1,5)) 
    y <- c(rep(6,7), rep(1,6), rep(6,5)) 
    z <- c(5,0,0,0,1,0,0,0,0,1,0,0,0,4,2,1,0,1) 
    updated_y0 <- c(6,1,1,1,1,0,0,1,1,1,0,0,0,6,2,0,-1,-2) 

dat2 <- data.frame(ID, t, y, z, updated_y0) 
+0

也许我不理解,但对于第2部分,你的意思是'updated_y0(1,2)= updated_y0(1,1) - z(1,1)'?而不只是'updated_y0(1,2)= y(1,1) - z(1,1)' –

+0

是的。这意味着对于每个id,从第二行开始,updated_y0是前一个y和z之间的差值。谢谢 – user9292

+0

是的,我的问题是你想要它是'YZ或'previous_y0 - z'。你提供的例子,'updated_y0(1,3)'上面没有'1-0'。 –

回答

1

这应该工作,虽然我讨厌使用for循环。首先,我们确定的所有第一记录每个ID(所有其他人将被标记NA):

library(dplyr) 

dat2 <- dat1 %>% 
    group_by(ID) %>% 
    mutate(updated_y0 = ifelse(t == 1, 
          y, 
          NA)) 

现在我们用一个for循环,只更换NAs

for(i in 1:nrow(dat2)){ 
    dat2$updated_y0[i] <- ifelse(is.na(dat2$updated_y0[i]), 
           dat2$updated_y0[i-1] - dat2$z[i-1], 
           dat2$updated_y0[i]) 
    } 

dat2 

对于示例的滞后y-z选项,您可以使用dplyr选项非常简单:

dat1 %>% 
    group_by(ID) %>% 
    mutate(updated_y0 = ifelse(t == 1, 
          y, 
          lag(y - z))) 

ifelse给出当前值y的值,只要它是第一条记录(t)。如果它不是ID的第二条记录,则它会根据上面的行计算y-zdplyr::lag)。

+0

谢谢戴夫! – user9292

相关问题