在两列上有条件地分配值或删除行

时间:2017-03-05 11:07:02

标签: r conditional transform

我刚刚合并了R中的纵向数据并发现了一个问题。我的数据框df看起来(大致)是这样的:

Clinic   ID   Year    Result  
A         1   2000        50
A         1   2002
A         1   2004     
A         2   2000      
A         2   2002      
A         2   2004      1100
B         1   2000
B         1   2002
B         1   2004 

我们需要患有测试结果的患者的所有年份数据,以及将结果值分配给该患者的所有行的方法。我需要丢弃没有记录结果的患者。在这个例子中,我需要在诊所A保留患者1和2的所有行,但是在诊所B丢弃患者1的所有行。此外,在诊所AI需要所有患者1的行列出“50”,因为是他的测试结果。

我认为最终我可以使用:df [!is.na(df $ Result),] ...但我无法弄清楚如何在删除之前将“结果”值共享给所有相关行的NA。

df <- transform(df, NewResult = (Clinic, ID, Fun=Function(Result) ifelse(Result>0 == Result, NA))

这不起作用;它返回了一个错误。指导非常感谢。

我需要的是:

Clinic   ID   Year    Result  
A         1   2000        50
A         1   2002        50
A         1   2004        50
A         2   2000      1100
A         2   2002      1100
A         2   2004      1100
B         1   2000        NA
B         1   2002        NA
B         1   2004        NA

1 个答案:

答案 0 :(得分:1)

我们可以使用na.locf中的zoo执行此操作,以便在按“诊所”和“ID”分组后用非NA值填充NA值

library(data.table)
library(zoo)
setDT(df)[, Result := na.locf(na.locf(Result, na.rm = FALSE), 
                        fromLast=TRUE, na.rm = FALSE), .(Clinic, ID)]

或者我们可以使用fill

中的tidyverse
library(tidyverse)
df %>% 
   group_by(Clinic, ID) %>% 
   fill(Result) %>%
   fill(Result, .direction = "up")    
#   Clinic    ID  Year Result
#   <chr> <int> <int>  <int>
#1      A     1  2000     50
#2      A     1  2002     50
#3      A     1  2004     50
#4      A     2  2000   1100
#5      A     2  2002   1100
#6      A     2  2004   1100
#7      B     1  2000     NA
#8      B     1  2002     NA
#9      B     1  2004     NA