我如何在R中自动实现年龄等级的提升

时间:2019-04-29 19:27:16

标签: r dataframe

很抱歉,如果这是一个简单的问题,我对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 :(得分:0)

如果您有问题中ID和季节的数据框,以及年龄类的有序向量,如下所示:

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

然后,您可以将age_classes的向量与cumsum的{​​{1}}进行子集化,即,对该子集的索引等于该特定季节的季数等于3的次数行,以获取该行的age_class。

Season == 3

编辑:

如果每个ID都有一个起始年龄类别,则可以在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 向量中添加该类别的索引,而不是在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>

答案 1 :(得分:0)

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))