繁体   English   中英

与基线的列差异

[英]Column difference from baseline

这可能是一个重复的问题,如果是这样,我不会感到惊讶,

这是我正在处理的数据集的示例

ID    Type    Time1     Time2     Time3
1     A1      12.23     NA        NA
2     A1       0.35     0.53      NA
2     A2       5.78     NA        10.25
3     A5       NA       NA        4.19
4     A3       NA       3.18      7.15
5     A5       10.91    4.56      2.45

我的目标是像这样创建两列 [Delta1, Delta2]

Delta1 :此列仅存储 Time2-Time1 中的值之间的差异,仅在所有三个值都可用的行中:Time1、Time2、Time3。 例如最后一行 ID 5 具有所有三个时间的值,time1,time2,time3 所以 Delta1 = 4.56-10.91 = -6.35

Delta2 :此列存储 Time2-Time1 或 Time3-Time1 或 Time3-Time2 之间的差异。 如果一行没有任何两个时间值,则为 0

最终预期输出

ID    Type    Time1     Time2     Time3     Delta1     Delta2
1     A1      12.23     NA        NA                   0
2     A1       0.35     0.53      NA                   0.18
2     A2       5.78     NA        10.25                4.47  
3     A5       NA       NA        4.19                 0
4     A3       NA       3.18      7.15                 3.97
5     A5       10.91    4.56      2.45      -6.35     -2.11

非常感谢任何帮助,在此先感谢。

df$Delta1 <- ifelse(!is.na(df$Time1) & !is.na(df$Time2) & !is.na(df$Time3),
                    df$Time2 - df$Time1,
                    NA)

df$Delta2 <- vapply(seq_len(nrow(df)), \(x){
                                              x = na.omit(c(df$Time3[x], df$Time2[x], df$Time1[x]))
                                              x = x[1] - x[2]
                                              if(is.na(x)) return(0)
                                              return(x)
                                            }, 0)

结果:

> df
  ID Type Time1 Time2 Time3 Delta1 Delta2
1  1   A1 12.23    NA    NA     NA   0.00
2  2   A1  0.35  0.53    NA     NA   0.18
3  2   A2  5.78    NA 10.25     NA   4.47
4  3   A5    NA    NA  4.19     NA   0.00
5  4   A3    NA  3.18  7.15     NA   3.97
6  5   A5 10.91  4.56  2.45  -6.35  -2.11

使用dplyr ,您可以使用coalesce()来查找第一个非缺失元素。

library(dplyr)

df %>%
  mutate(Delta1 = ifelse(if_any(starts_with("Time"), is.na), NA, Time2-Time1),
         Delta2 = coalesce(Time3-Time2, Time3-Time1, Time2-Time1, 0))

#   ID Type Time1 Time2 Time3 Delta1 Delta2
# 1  1   A1 12.23    NA    NA     NA   0.00
# 2  2   A1  0.35  0.53    NA     NA   0.18
# 3  2   A2  5.78    NA 10.25     NA   4.47
# 4  3   A5    NA    NA  4.19     NA   0.00
# 5  4   A3    NA  3.18  7.15     NA   3.97
# 6  5   A5 10.91  4.56  2.45  -6.35  -2.11

您所说的标准对于Delta2的输出是不确定的,我已经选择了最大范围。

library(dplyr)

data %>% 
  rowwise() %>% 
  mutate(
    Delta1 = if_else(
      anyNA(c_across(starts_with("Time"))),
      0,
      Time2 - Time1
    ),
    Delta2 = diff(range(na.omit(c_across(starts_with("Time")))))
  ) 
#> # A tibble: 6 × 7
#> # Rowwise: 
#>      ID Type  Time1 Time2 Time3 Delta1 Delta2
#>   <dbl> <chr> <dbl> <dbl> <dbl>  <dbl>  <dbl>
#> 1     1 A1    12.2  NA    NA      0      0   
#> 2     2 A1     0.35  0.53 NA      0      0.18
#> 3     2 A2     5.78 NA    10.2    0      4.47
#> 4     3 A5    NA    NA     4.19   0      0   
#> 5     4 A3    NA     3.18  7.15   0      3.97
#> 6     5 A5    10.9   4.56  2.45  -6.35   8.46

要生成列 Delta 1,您还可以尝试以下操作...


data <- data %>% 
  dplyr::mutate(Delta1 = case_when(
    Time1 & Time2 & Time3!="NA" ~ Time2 - Time1))



不漂亮,但这适用于 Delta2 使用sapply

df$Delta2 <- sapply(seq_len(nrow(df)), function(x){
  items <- na.exclude(unlist(df[x,c("Time1", "Time2", "Time3")]))
  if(length(items) < 2) return(0)
  else return(items[length(items)] - items[length(items)-1])
})


  ID Type Time1 Time2 Time3 Delta2
1  1   A1 12.23    NA    NA   0.00
2  2   A1  0.35  0.53    NA   0.18
3  2   A2  5.78    NA 10.25   4.47
4  3   A5    NA    NA  4.19   0.00
5  4   A3    NA  3.18  7.15   3.97
6  5   A5 10.91  4.56  2.40  -2.16

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM