我有一个数据集如下
Id BMI Date Case CaseDate
1331 28.2 2012-05-15 No NA
1331 26.4 2011-04-06 No NA
1331 29.37 2014-04-01 No NA
5074 30.02 2009-10-23 Yes 2014-08-06
5074 25.12 2011-07-15 Yes 2014-08-06
我想做的是如下
1)对于Case=No
的ID,选择最接近当前日期(Sys.Date ())
的BMI并将此值存储在新列(New_BMI
)
2)对于Case=Yes
的ID,选择最接近CaseDate
列中日期的BMI并将此值存储在新列(New_BMI
)
最终输出应如下所示。
Id BMI Date Case CaseDate New_BMI
1331 28.2 2012-05-15 No NA 29.37
1331 26.4 2011-04-06 No NA 29.37
1331 29.37 2014-04-01 No NA 29.37
5074 30.02 2009-10-23 Yes 2014-08-06 25.12
5074 25.12 2011-07-15 Yes 2014-08-06 25.12
Id 1331的New_BMI
值为29.37,因为这是最接近当前日期的值。 Id 5074的New_BMI
值为25.12,因为这是最接近CaseDate
的值(2014-08-06)。
有关如何计算此New_BMI
的任何帮助都非常感谢大家。
答案 0 :(得分:2)
首先确保你有Date类对象。
df$Date <- as.Date(df$Date)
df$CaseDate <- as.Date(df$CaseDate)
然后使用dplyr,一种方法是按ID分组并测试条件。主函数调用是BMI[which.min(Sys.Date() - Date)]
。这会将BMI列设置为当前日期与Date
列之间的最小长度。 CaseDate
也是如此。
library(dplyr)
df %>%
group_by(Id) %>%
mutate(New_BMI = ifelse(Case == "No", BMI[which.min(Sys.Date() - Date)],
BMI[which.min(CaseDate - Date)]))
# Source: local data frame [5 x 6]
# Groups: Id [2]
#
# Id BMI Date Case CaseDate New_BMI
# (int) (dbl) (date) (fctr) (date) (dbl)
# 1 1331 28.20 2012-05-15 No <NA> 29.37
# 2 1331 26.40 2011-04-06 No <NA> 29.37
# 3 1331 29.37 2014-04-01 No <NA> 29.37
# 4 5074 30.02 2009-10-23 Yes 2014-08-06 25.12
# 5 5074 25.12 2011-07-15 Yes 2014-08-06 25.12
数据强>
df <- structure(list(Id = c(1331L, 1331L, 1331L, 5074L, 5074L), BMI = c(28.2,
26.4, 29.37, 30.02, 25.12), Date = structure(c(4L, 2L, 5L, 1L,
3L), .Label = c("2009-10-23", "2011-04-06", "2011-07-15", "2012-05-15",
"2014-04-01"), class = "factor"), Case = structure(c(1L, 1L,
1L, 2L, 2L), .Label = c("No", "Yes"), class = "factor"), CaseDate = structure(c(NA,
NA, NA, 1L, 1L), .Label = "2014-08-06", class = "factor")), .Names = c("Id",
"BMI", "Date", "Case", "CaseDate"), class = "data.frame", row.names = c(NA,
-5L))