Как я могу автоматизировать возрастные классы в R - PullRequest
0 голосов
/ 29 апреля 2019

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

В настоящее время я пытаюсь использовать операторы if-else для решения моей проблемы.но я чувствую, что снимаю в темноте, как правильно отформатировать.По сути, мне нужно, чтобы мой код распознал сезон наблюдения, если сезон не три, то результатом должен быть исходный возрастной класс (если это первое наблюдение) или возрастной класс предыдущего наблюдения.

Если сезон 3, то мне нужно повышение по возрасту.Например, если человек был однолетним в предыдущем наблюдении, запись следующего сезона 3 изменила бы возрастной класс индивидуума с однолетнего на взрослого.Но если бы этот человек был взрослым, возрастная группа осталась бы прежней.

Ниже приведен пример того, как мне нужны данные, чтобы выглядеть.

+----+--------+--------------------+----------------+
| ID | Season | Original Age Class | Desired Output |
+----+--------+--------------------+----------------+
|  1 |      1 | New_Born           | New_Born       |
|  1 |      2 |                    | New_Born       |
|  1 |      3 |                    | Yearling       |
|  1 |      4 |                    | Yearling       |
|  1 |      1 |                    | Yearling       |
|  1 |      2 |                    | Yearling       |
|  1 |      3 |                    | Adult          |
|  1 |      4 |                    | Adult          |
|  1 |      1 |                    | Adult          |
|  1 |      2 |                    | Adult          |
+----+--------+--------------------+----------------+

Буду признателен за любую помощь в решении моей проблемы и заранее благодарю вас.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

Базовым решением R может быть следующее.

ageclass <- c('New_Born', 'Yearling', 'Adult')

sp <- split(df1, df1$ID)
result <- lapply(sp, function(DF){
  f <- cumsum(DF[['Season']] == 3) + 1
  i <- which(ageclass %in% DF[[3]])
  if(i > 1) f <- f + 1
  f[f > 3] <- 3
  DF[['New']] <- ageclass[f]
  DF
})

result <- do.call(rbind, result)
row.names(result) <- NULL
result

Обратите внимание, что я проверил с Original Age Class, равным "Yearling", и оно сработало.

Данные.

x <-"
+----+--------+--------------------+----------------+
  | ID | Season | `Original Age Class` | `Desired Output` |
  +----+--------+--------------------+----------------+
  |  1 |      1 | New_Born           | New_Born       |
  |  1 |      2 |                    | New_Born       |
  |  1 |      3 |                    | Yearling       |
  |  1 |      4 |                    | Yearling       |
  |  1 |      1 |                    | Yearling       |
  |  1 |      2 |                    | Yearling       |
  |  1 |      3 |                    | Adult          |
  |  1 |      4 |                    | Adult          |
  |  1 |      1 |                    | Adult          |
  |  1 |      2 |                    | Adult          |
  +----+--------+--------------------+----------------+"


df1 <- data.table::fread(gsub('\\+.+\\n' ,'', x, perl = T), drop=c(1,6))
0 голосов
/ 29 апреля 2019

Если у вас есть фрейм данных идентификаторов и сезонов, как в вашем вопросе, и упорядоченный вектор возрастных классов, как показано ниже:

df <- data.frame(ID = rep(1, 10), Season = rep_len(1:4, 10))
age_classes <- c('New_Born', 'Yearling', 'Adult')

Затем можно задать для вектора age_classes значение cumsum, равное Season == 3, то есть для подмножества вектора с индексом, равным числу времен сезона, равным 3 для этой конкретной строки, получим эту строку. age_class.

library(data.table)
setDT(df)

df[, age_class := age_classes[cumsum(Season == 3) + 1], 
   by = ID]

df
#     ID Season age_class
#  1:  1      1  New_Born
#  2:  1      2  New_Born
#  3:  1      3  Yearling
#  4:  1      4  Yearling
#  5:  1      1  Yearling
#  6:  1      2  Yearling
#  7:  1      3     Adult
#  8:  1      4     Adult
#  9:  1      1     Adult
# 10:  1      2     Adult

Edit:

Если у каждого идентификатора есть начальный возрастной класс, вы можете добавить индекс этого класса в векторе age_classes вместо 1 к выходу cumsum.

Исходные данные

df <- data.frame(ID = rep(1, 10), Season = rep_len(1:4, 10), 
                 orig_age_class = c('New_Born', rep(NA, 9)))
age_classes <- c('New_Born', 'Yearling', 'Adult')



#    ID Season orig_age_class
# 1   1      1       New_Born
# 2   1      2           <NA>
# 3   1      3           <NA>
# 4   1      4           <NA>
# 5   1      1           <NA>
# 6   1      2           <NA>
# 7   1      3           <NA>
# 8   1      4           <NA>
# 9   1      1           <NA>
# 10  1      2           <NA>

Код и вывод

library(data.table)
setDT(df)

df[, age_class := {
        start_ind <- match(orig_age_class[1], age_classes)
        n3 <- cumsum(Season == 3)
        age_classes[pmin(length(age_classes), n3 + start_ind)]}, 
   by = ID]

df
#     ID Season orig_age_class age_class
#  1:  1      1       New_Born  New_Born
#  2:  1      2           <NA>  New_Born
#  3:  1      3           <NA>  Yearling
#  4:  1      4           <NA>  Yearling
#  5:  1      1           <NA>  Yearling
#  6:  1      2           <NA>  Yearling
#  7:  1      3           <NA>     Adult
#  8:  1      4           <NA>     Adult
#  9:  1      1           <NA>     Adult
# 10:  1      2           <NA>     Adult
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...