2016-01-24 37 views
2

比方说,我有一个数据帧如下:动态创建

BID diff 
1 1 NA 
2 1 0.0 
3 1 0.0 
4 1 -0.5 
5 1 0.0 
6 1 0.0 
7 1 0.0 
8 1 0.5 
9 1 0.0 
10 1 0.0 
11 2 NA 
12 2 0.0 
13 2 0.0 
14 2 0.0 
15 2 -0.5 
16 2 0.0 
17 2 0.0 
18 2 0.0 
19 2 0.0 
20 3 NA 
21 3 0.5 
22 3 0.0 
23 3 -0.5 
24 3 0.5 

我想要做的是,为每个BID,创建一个新的变量neg等于在负值diff之前为0,在负值diff之后等于1。但是当diff再次改变时它应该停止。例如。

BID diff neg 
1 1 NA 0 
2 1 0.0 0 
3 1 0.0 0 
4 1 -0.5 NA 
5 1 0.0 1 
6 1 0.0 1 
7 1 0.0 1 
8 1 0.5 NA 
9 1 0.0 NA 
10 1 0.0 NA 
11 2 NA 0 
12 2 0.0 0 
13 2 0.0 0 
14 2 0.0 0 
15 2 -0.5 NA 
16 2 0.0 1 
17 2 0.0 1 
18 2 0.0 1 
19 2 0.0 1 
20 3 NA NA 
21 3 0.5 NA 
22 3 0.0 0 
23 3 -0.5 NA 
24 3 0.5 NA 

我试图接近跑着“1个与dplyr如下:

data <- data %>% 
    group_by(BID) %>% 
    mutate(neg = 
     as.numeric(
      ifelse(lag(diff) == -0.5, 1, 
        ifelse(((lag(neg) == 1) & (diff == 0.0)), 
             lag(neg), 0)))) 

我想它现在是有点明显,如果这仅适用于需要两个或更少1的按照diff -0.5。

任何帮助将不胜感激,除了dplyr之外,我也接受其他方法。数据本身是一个时间序列,diff是每个BID的另一个变量的当前值和滞后值之差。如果有其他信息可能会有所帮助,请告知我们。

回答

1

这可能不是做最有效的方式,但在这里你去:

df <- read.table(text = ' BID diff 
       1 1 NA 
       2 1 0.0 
       3 1 0.0 
       4 1 -0.5 
       5 1 0.0 
       6 1 0.0 
       7 1 0.0 
       8 1 0.5 
       9 1 0.0 
       10 1 0.0 
       11 2 NA 
       12 2 0.0 
       13 2 0.0 
       14 2 0.0 
       15 2 -0.5 
       16 2 0.0 
       17 2 0.0 
       18 2 0.0 
       19 2 0.0 
       20 3 NA 
       21 3 0.5 
       22 3 0.0 
       23 3 -0.5 
       24 3 0.5', header = FALSE) 

df[is.na(df)] <- 0 
df$neg <- 0 

for (i in 1:length(df$diff)) { 
    flag <- ifelse(df$diff[i] < 0, 1, 0) 
    if (flag == 1) { 
    for (j in i:length(df$diff)) { 
     if (df$diff[j] > 0) { 
     flag <- 0 
     break 
     } else { 
     df$neg[j] <- 1 
     } 
    } 
    } 
} 

df$neg[df$diff < 0] <- 0 
df 
## BID diff neg 
## 1 1 0.0 0 
## 2 1 0.0 0 
## 3 1 0.0 0 
## 4 1 -0.5 0 
## 5 1 0.0 1 
## 6 1 0.0 1 
## 7 1 0.0 1 
## 8 1 0.5 0 
## 9 1 0.0 0 
## 10 1 0.0 0 
## 11 2 0.0 0 
## 12 2 0.0 0 
## 13 2 0.0 0 
## 14 2 0.0 0 
## 15 2 -0.5 0 
## 16 2 0.0 1 
## 17 2 0.0 1 
## 18 2 0.0 1 
## 19 2 0.0 1 
## 20 3 0.0 1 
## 21 3 0.5 0 
## 22 3 0.0 0 
## 23 3 -0.5 0 
## 24 3 0.5 0 

发生了什么事是:每次发现在diff负数,它设置一个标志,并改变所有的以下值为1,直到它找到一个正数。

+0

我不认为这是所需的输出。这里也应该有'NAs'。 –

+0

感谢您的建议,它比我所得到的更接近。不幸的是大卫是正确的,因为它不是理想的输出。最重要的是,因为它忽略了团体。例如,'df $ neg [20]'当然不应该是1.我试图用data.table来解决一个功能性的解决方案,但它肯定是效率低下的。 – James