2016-08-15 3 views
5

У меня есть вопрос относительно data.table в 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 

Теперь я хочу, чтобы создать третий столбец с, который собираемся сравнить значение каждой строки a со всеми предыдущими значениями b и проверить, есть ли какое-либо значение b больше, чем a. Например, в строке 5 a = 5, а предыдущее значение b равно 1,5,6,7. так 6 и 7 больше, чем 5, поэтому значение с должно быть 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 

Я попытался с цикл, но это занимает очень много времени , Я также попытался сдвиг, но я не могу ссылаться на несколько предыдущих строк со сдвигом. У кого-нибудь есть рекомендации?

ответ

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%>% (c = as.integer (a Sumedh

+0

Следует отметить, что ваше первое решение - это базовое решение для обработки данных, которое не использует эффективность data.table. –

+0

@DeanMacGregor Спасибо за предложение, мне потребуется некоторое время, чтобы придумать решение 'data.table', поскольку я больше знаком с' dplyr'. – steveb

Смежные вопросы