2017-08-01 194 views
0

我有一个数据帧(如下所示)列的值:操纵基于另一列

df <- read.table(header = TRUE, text = 
      "STUD_ID  MEAS VALUE 
       1 LVEF(M-M) 69 
       1 LVEF(2D) 66 
       2 LVEF(2D) 36 
       2 LVEF(2D) 72 
       2  IVSD 63 
       3 LVEF(M-M) 50 
       4 LVEF(2D) 71 
       4  PASP 55", stringsAsFactors = FALSE) 

我希望把重点放在MEAS是要么LVEF(M-M)LVEF(2D)

  1. 如果STUD_ID具有VALUE s表示对应于两个LVEF(M-M)LVEF(2D),那么我们只筛选后者即LVEF(2D)
  2. 如果一个STUD_ID有2个VALUE s对应于LVEF(2D),那么我们取平均值。

我所需的输出是:

# STUD_ID  MEAS VALUE 
#  1 LVEF(2D) 66 
#  2 LVEF(2D) 54 
#  2  IVSD 63 
#  3 LVEF(M-M) 50 
#  4 LVEF(2D) 71 
#  4  PASP 55 

我尝试以下,但它给了我一个错误:

df %>% 
    filter(MEAS == "LVEF(M-M)" | MEAS == "LVEF(2D)") %>% 
    arrange(STUD_ID, MEAS) %>% 
    group_by(STUD_ID, MEAS) %>% 
    mutate(n = n()) %>% 
    group_by(STUD_ID) %>% 
    mutate(nd = n_distinct(MEAS)) %>% 
    mutate(VALUE = 
      case_when(nd == 2 ~ VALUE[which(MEAS == "LVEF(2D)")], 
        nd == 1 & n > 1 ~ mean(VALUE), 
        TRUE ~ VALUE)) %>% 
    bind_rows(
    df %>% filter(MEAS != "LVEF(M-M)" & MEAS != "LVEF(2D)") 
) 

我的数据帧中包含的其他变量除了这3个变量,我想保留它们。

回答

1

这确实你在找什么...

df2 <- df %>% group_by(STUD_ID,MEAS) %>% 
    summarise(VALUE=mean(VALUE)) %>% 
    group_by(STUD_ID) %>% mutate(TEMP2D=("LVEF(2D)" %in% MEAS)) %>% 
    filter(!(MEAS=="LVEF(M-M)" & TEMP2D)) %>% 
    select(-TEMP2D) 

df2 
# A tibble: 6 x 3 
# Groups: STUD_ID [4] 
    STUD_ID  MEAS VALUE 
    <int>  <chr> <dbl> 
1  1 LVEF(2D) 66 
2  2  IVSD 63 
3  2 LVEF(2D) 54 
4  3 LVEF(M-M) 50 
5  4 LVEF(2D) 71 
6  4  PASP 55 
+0

我必须做一些连接,如果我有这三个,我还是想在最后的数据集保留旁边的其他变量? – HNSKD

+1

这取决于你想要对其他变量进行平均的行 - 你可以在'summarise'中包含它们,或者在'df'结尾包含它们的'left_join'。请注意,如果每个ID有多个,上面的代码也会对任何“IVSD”或“PASP”行进行平均 - 这可能是也可能不是您想要的。 –