[英]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.