2015-11-24 3 views
7

Я хотел бы вернуть новый столбец в таблице данных. Это показывает, сколько строк осталось до тех пор, пока не будет достигнуто значение ниже текущего значения (Temp).R data.table count rows до достижения значения

library(data.table) 
set.seed(123) 
DT <- data.table(Temp = runif(10,0,20)) 

Это, как я хотел бы, чтобы это выглядело:

set.seed(123) 
DT <- data.table(
     Temp = runif(10,0,20), 
     Day_Below_Temp = c("5","1","3","2","1","NA","3","1","1","NA") 
) 

ответ

2

Вот dplyr метод:

library(dplyr) 
set.seed(123) 
dt <- data.frame(Temp = runif(10,0,20)) 
dt %>% mutate(Day_Below_Temp = 
       sapply(1:length(Temp), function(x) min(which(.$Temp[x:length(.$Temp)] < .$Temp[x]))-1)) 

     Temp Day_Below_Temp 
1 5.751550    5 
2 15.766103    1 
3 8.179538    3 
4 17.660348    2 
5 18.809346    1 
6 0.911130   Inf 
7 10.562110    3 
8 17.848381    1 
9 11.028700    1 
10 9.132295   Inf 
+0

Ok это здорово @jeremycg, и убедиться, что я правильно понимаю, если бы я хотел, чтобы проверить, что грести значение Temp пошел ниже, чем альтернативный колонке (дополнительный столбец) значение, как этот метод изменится? Спасибо – user3740289

+0

Нет проблем. Вы бы изменили '. $ Temp [x: length (. $ Temp)]' to '. $ Дополнительнаяcolumn [x: length (. $ Temp)]'. – jeremycg

+1

К сожалению, этот (и мой собственный удаленный ответ) кажется медленным, как мокрая неделя. Даже при 100K случаях это занимает минута плюс. Я думаю, что должен быть способ обойти это через некоторые объединения или что-то сложное. Арун, где ты ?! – thelatemail

1

Это делает работу - не очень быстро, хотя

DT[, rowN := .I] 

DT[, Day_Below_Temp := which(DT$Temp[rowN:nrow(DT)] < Temp)[1] - 1, 
    by = rowN 
    ][, rowN := NULL] 
4

Использование недавно реализованного n на оборудах включается в текущей разрабатываемой версии, это может быть достигнуто простым способом следующим образом:

require(data.table) # v1.9.7+ 
DT[, row := .I] # add row numbers 
DT[DT, x.row-i.row, on = .(row > row, Temp < Temp), mult="first"] 
# [1] 5 1 3 2 1 NA 3 1 1 NA 

Номер строки необходим, так как нам нужно найти показатели ниже, чем текущий индекс, следовательно, должен быть условие в соединении. Мы выполняем самосоединение , то есть для каждой строки в DT (внутренний), на основании условия, предоставленного аргументу on, мы находим первый соответствующий индекс строки в DT (внешний). Затем мы вычитаем индексы строк, чтобы получить позицию из текущей строки. x.row относится к индексу внешнего DT и i.row к внутреннему DT.

Чтобы получить версию devel, см. Инструкцию по установке here.


На 1e5 строк:

set.seed(123) 
DT <- data.table(Temp = runif(1e5L, 0L, 20L)) 

DT[, row := .I] 
system.time({ 
    ans = DT[DT, x.row-i.row, on = .(row > row, Temp < Temp), mult="first", verbose=TRUE] 
}) 
# Non-equi join operators detected ... 
# forder took ... 0.001 secs 
# Generating non-equi group ids ... done in 0.452 secs 
# Recomputing forder with non-equi ids ... done in 0.001 secs 
# Found 623 non-equi group(s) ... 
# Starting bmerge ...done in 8.118 secs 
# Detected that j uses these columns: x.row,i.row 
# user system elapsed 
# 8.492 0.038 8.577 

head(ans) 
# [1] 5 1 3 2 1 12 
tail(ans) 
# [1] 2 1 1 2 1 NA 
Смежные вопросы