假设我有一个数据框,其中有几行如下所示的内容:
对于每一行,我想获取根据日期(分别查看date1、date2或date3并选择最近的日期)在a、b和c之间不是NA的最新值。基本上,date1给出与值a对应的日期,date2给出与值b对应的日期,date3给出与值c对应的日期。
如果date1> date2且date1> date3,则我将希望取值a。但是,如果值a为NA(在我的示例中是这种情况),则我将比较date2和date3。在我的示例中,date2> date3,由于值b不是NA而是50,因此我将以50作为最终结果。
现在我想针对数据框中的所有行执行此操作
由于我使用了dplyr,我尝试使用case_when函数通过使用rank函数(在我的示例中,我查看第一个排名日期,然后查看链接值。如果它为NA,则查看排名第二好的等等)。
然而,我不能像我想做的那样简单地放置:
因为
在我的例子中,我想要的结果是:
有没有人对这个问题有想法,或者甚至有完全不同的解决方法?
df <- data.frame(a = c(NA,20,NA),
date1 = c("2016-03-01", "2016-02-01", "2016-02-01"),
b = c(50,NA, NA),
date2 = c("2016-02-01", "2016-03-01", "2016-03-01"),
c = c(10,10, 10),
date3 = c("2016-01-01","2016-01-01", "2016-01-01"))
对于每一行,我想获取根据日期(分别查看date1、date2或date3并选择最近的日期)在a、b和c之间不是NA的最新值。基本上,date1给出与值a对应的日期,date2给出与值b对应的日期,date3给出与值c对应的日期。
如果date1> date2且date1> date3,则我将希望取值a。但是,如果值a为NA(在我的示例中是这种情况),则我将比较date2和date3。在我的示例中,date2> date3,由于值b不是NA而是50,因此我将以50作为最终结果。
现在我想针对数据框中的所有行执行此操作
由于我使用了dplyr,我尝试使用case_when函数通过使用rank函数(在我的示例中,我查看第一个排名日期,然后查看链接值。如果它为NA,则查看排名第二好的等等)。
然而,我不能像我想做的那样简单地放置:
df <- df %>%
mutate(result = case_when(is.na(a) & is.na(b) & is.na(c) ~ NA_integer_,
rev(rank(date1, date2, date3))[1] == 3 & !is.na(a) ~ a,
rev(rank(date1, date2, date3))[2] == 3 & !is.na(b) ~ b,
rev(rank(date1, date2, date3))[3] == 3 & !is.na(a) ~ c,
rev(rank(date1, date2, date3))[1] == 2 & !is.na(a) ~ a,
rev(rank(date1, date2, date3))[2] == 2 & !is.na(b) ~ b,
rev(rank(date1, date2, date3))[3] == 2 & !is.na(a) ~ c,
rev(rank(date1, date2, date3))[1] == 1 & !is.na(a) ~ a,
rev(rank(date1, date2, date3))[2] == 1 & !is.na(b) ~ b,
rev(rank(date1, date2, date3))[3] == 1 & !is.na(a) ~ c))
因为
rank
函数需要一个唯一的向量作为参数(但是我不能把c(date1, date2, date3)
放进去,因为它会给我整个向量的顺序而不是每行的等级)。在我的例子中,我想要的结果是:
res
a date1 b date2 c date3 result
NA 2016-03-01 50 2016-02-01 10 2016-01-01 50
20 2016-02-01 NA 2016-03-01 10 2016-01-01 20
NA 2016-02-01 NA 2016-03-01 10 2016-01-01 10
有没有人对这个问题有想法,或者甚至有完全不同的解决方法?