2016-08-15 70 views
5

我有一个关于在R 我有这样如何引用多个先前的行中的R data.table

data <- data.table(a=c(1:7,12,32,13),b=c(1,5,6,7,8,3,2,5,1,4)) 

    a b 
1: 1 1 
2: 2 5 
3: 3 6 
4: 4 7 
5: 5 8 
6: 6 3 
7: 7 2 
8: 12 5 
9: 32 1 
10: 13 4 

数据集data.table问题现在我想产生第三列c,其将a的每一行的值与b的所有以前的值进行比较,并检查b的任何值是否大于a。例如,在第5行,a = 5,b的先前值是1,5,6,7。因此图6和7是大于5,因此的C值应为1,否则这将是0。 结果应该是这样的

 a b c 
1: 1 1 NA 
2: 2 5 0 
3: 3 6 1 
4: 4 7 1 
5: 5 8 1 
6: 6 3 1 
7: 7 2 1 
8: 12 5 0 
9: 32 1 0 
10: 13 4 0 

我与一个for循环尝试,但它需要很长的时间。我也尝试过换档,但是我不能用换档来引用多个先前的排。任何人有任何建议?

回答

5
library(data.table) 
data <- data.table(a=c(1:7,12,32,13),b=c(1,5,6,7,8,3,2,5,1,4)) 
data[,c:= a <= shift(cummax(b))] 
+2

这对于OP来说更像是一个点 - 你是否真的想要一些显然是逻辑对象的东西来存储为一个整数?我理解想要整数的本能,但如果你问我,逻辑上的列应该被存储为“逻辑” – MichaelChirico

2

这是一个基础R溶液(见下面的dplyr溶液):

data$c = NA 
data$c[2:nrow(data)] <- sapply(2:nrow(data), function(x) { data$c[x] <- any(data$a[x] < data$b[1:(x-1)]) }) 

##  a b c 
## 1: 1 1 NA 
## 2: 2 5 0 
## 3: 3 6 1 
## 4: 4 7 1 
## 5: 5 8 1 
## 6: 6 3 1 
## 7: 7 2 1 
## 8: 12 5 0 
## 9: 32 1 0 
## 10: 13 4 0 

EDIT

这里使用dplyr

library(dplyr) 
### Given the cumulative max and comparing to 'a', set see to 1/0. 
data %>% mutate(c = ifelse(a < lag(cummax(b)), 1, 0)) 

##  a b c 
## 1 1 1 NA 
## 2 2 5 0 
## 3 3 6 1 
## 4 4 7 1 
## 5 5 8 1 
## 6 6 3 1 
## 7 7 2 1 
## 8 12 5 0 
## 9 32 1 0 
## 10 13 4 0 

### Using 'shift' with dplyr 
data %>% mutate(c = ifelse(a <= shift(cummax(b)), 1, 0)) 
+0

也许你一个简单的解决方案可以使用这个'data%>%mutate(c = as.integer(a Sumedh

+0

需要注意的一件事是,您的第一个解决方案是不利用data.table效率的基础数据框解决方案。 –

+0

@DeanMacGregor感谢您的建议,我需要一段时间才能提出'data.table'解决方案,因为我更熟悉'dplyr'。 – steveb

相关问题