Номер строки увеличивается на указанные c условия более быстрым способом R - PullRequest
0 голосов
/ 18 февраля 2020

Фрейм данных, который я выглядел следующим образом.

enter image description here

переменная "rank" должна быть увеличена, как только разница между [i] th строка «start» и [i-1] -ая строка «end» превышают 14. (также, когда встречаются разные «ID»)

Я попробовал приведенный ниже код, и он работал очень хорошо.

Но дело в том ... что это слишком медленно, потому что у меня более 700000 строк.

Итак, есть ли способ заставить его работать намного быстрее?


df$rank <- 1

for(i in 2:nrow(l50.df)){
  df[i,"rank"] <- ifelse((df[i,"ID"]==df[i-1,"ID"])&
                                   (df[i-1,"diff"]<=14), 
                         df[i,"rank"] <- df[i-1,"rank"],
                         df[i,"rank"] <- df[i-1,"rank"] + 1)
}

Ответы [ 3 ]

2 голосов
/ 18 февраля 2020

Вы можете попробовать:

library(dplyr)
df %>% mutate(rank  = cumsum(diff > 14 | ID != lag(ID, default = TRUE)))

Те же логики c с использованием базы R:

df$rank <- with(df, cumsum(diff > 14 | c(TRUE, tail(ID, -1) != head(ID, -1))))
1 голос
/ 18 февраля 2020

Вы можете использовать cumsum, чтобы получить повышение ранга при выполнении условий df[i,"ID"]==df[i-1,"ID"]) & (df[i-1,"diff"]<=14).

df$rank <- cumsum(c(1,(df$ID != c(df$ID[-1], NA) | df$diff>14)[-nrow(df)]))
df
#   ID diff rank
#1   a    4    1
#2   a    6    1
#3   a    8    1
#4   a  870    1
#5   a   34    2
#6   a   NA    3
#7   b    4    4
#8   b    6    4
#9   b    8    4
#10  b  870    4
#11  b   34    5
#12  b   NA    6

Используя ваш код:

df$rank <- 1
for(i in 2:nrow(df)){
  df[i,"rank"] <- ifelse((df[i,"ID"]==df[i-1,"ID"]) & (df[i-1,"diff"]<=14), 
    df[i,"rank"] <- df[i-1,"rank"], df[i,"rank"] <- df[i-1,"rank"] + 1)
}
df
#   ID diff rank
#1   a    4    1
#2   a    6    1
#3   a    8    1
#4   a  870    1
#5   a   34    2
#6   a   NA    3
#7   b    4    4
#8   b    6    4
#9   b    8    4
#10  b  870    4
#11  b   34    5
#12  b   NA    6

Данные:

df  <- data.frame(ID=rep(c("a","b"), each=6), diff=c(4,6,8,870,34,NA)
                  , stringsAsFactors = FALSE)
df
#   ID diff
#1   a    4
#2   a    6
#3   a    8
#4   a  870
#5   a   34
#6   a   NA
#7   b    4
#8   b    6
#9   b    8
#10  b  870
#11  b   34
#12  b   NA
0 голосов
/ 18 февраля 2020

Вот базовое решение R с использованием ave + ifelse

df <- within(df,rank <- ave(diff>14, diff>14,ID,FUN = function(x) ifelse(x,seq(x),+!x)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...