按 R 中患者的降序排列计算函数的 list()

问题描述 投票:0回答:1

我正在尝试计算包含大量数据的数据集的床上时间(TIB),其中包括他们上床睡觉的时间(inbed)和他们起床的时间(uitbed)。我的代码可以在较小的练习数据库(不到 10 天)中运行,但是当我使用超过 10 天的数据时,列表顺序会出错,因此 TIB 值会粘贴到表中的错误行中.

我的样本数据:

acti_sd <- data.frame(
  patient = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11),
  diagnosis = c(1, 1, 4, 5, 4, 1, 2, 2, 5, 3, 4),
  SDa1_inbed = c("19:00", "20:00", "18:30", "23:00", "20:00", "20:00", "20:00", "18:30", "20:00", "18:30", "20:00"),
  SDa2_inbed = c("01:00", "00:00", "23:25", "00:00", "22:45", "00:15", "00:00", "23:25", "00:00", "23:25", "00:00"),
  SDa1_uitbed = c("06:15", "10:00", "09:00", "08:00", "99:99", "06:15", "10:00", "09:00", "10:00", "09:00", "10:00"),
  SDa2_uitbed = c("09:30", "04:00", "08:30", "05:00", "06:30", "07:45", "04:00", "08:30", "04:00", "08:30", "04:00"),

我使用的代码是这样的(它成功计算了 TIB,但它没有正确排序列表:

#function
calc_TIB <- function(inbed, uitbed) {
  in_bed_time <- as.numeric(as.POSIXct(inbed, format = "%H:%M"))
  out_bed_time <- as.numeric(as.POSIXct(uitbed, format = "%H:%M"))
#if go to bed past or before midnight 
  out_bed_time <- ifelse(out_bed_time < in_bed_time, out_bed_time + 86400, out_bed_time)
#convert back to hours
  tib <- (out_bed_time - in_bed_time) / 3600
  
  return(tib)
}

#perform function for every patient and day
result <- lapply(split(long_wide_actisd[, c("inbed", "uitbed")],
    list(long_wide_actisd$SDa_day, long_wide_actisd$patient)), 
                 function(x)calc_TIB(x$inbed, x$uitbed))

#turn it into a matrix
SDa_TIB <- do.call(rbind, result)

#add tib matrix into table as a new column
long_wide_actisd <- cbind(long_wide_actisd, SDa_TIB)

print(long_wide_actisd)

这以顺序如下“SDa1.1、SDa10.1、SDa11.1”等的方式组织 TIB 数据。我尝试在列表中切换患者和 SDa_day,但随后它给出的顺序为“1 SDa1、2 SDa1、3 SDa1 等”我希望列表的组织方式与我的数据相同,即“SDa1.1、SDa2.1、SDa3.1”或“1 SDa1、1 SDa2、1 SDa3”每个患者的数据按 SDa 天数递减进行组织(没有优先考虑 10、11 等,因为它确实在数据库中完成了我想要的操作,每个患者的时间少于 10 天)。我需要以这种方式组织数据,以便粘贴正确地进入我的表。 我添加了一张上述两个选项的图片,这可能有助于更好地理解它。谁能帮我解决这个问题吗? picture of output

(我添加了一些与我正在使用的类似的示例数据,以下代码是我用来以我使用它的方式旋转表格并处理 NA 的代码):

acti_sd[acti_sd == '99:99'] <- NA

long_actisd <- SDa_data%>%
  pivot_longer(cols = !c(patient, diagnosis), 
               names_to = c("SDa_day", "measurementtype"),
               names_sep = "_",
               values_to = "measurement"
               ) 
long_actisd
long_wide_actisd <- long_actisd|>
  pivot_wider(names_from = "measurementtype", 
              values_from = "measurement")

再次感谢任何帮助,谢谢!

r list split lapply rbind
1个回答
0
投票

注意,我在示例数据中添加了一列,以更好地重现问题。

在基数 R 中,按

patient
SDa_day

的数字部分排序
long_wide_actisd <- long_wide_actisd[order(long_wide_actisd$patient, 
                       sub("\\D", "", long_wide_actisd$SDa_day)), ]

head(long_wide_actisd)
#          patient diagnosis SDa_day inbed uitbed   SDa_TIB
# SDa1.1         1         1    SDa1 19:00  06:15 11.250000
# SDa2.1         1         1   SDa10 01:00  06:15  8.500000
# SDa10.1        1         1    SDa2 01:00  09:30  5.250000
# SDa1.2         2         1    SDa1 20:00  10:00 14.000000
# SDa2.2         2         1   SDa10 00:00  10:00  4.000000
# SDa10.2        2         1    SDa2 00:00  04:00 10.000000
# SDa1.3         3         4    SDa1 18:30  09:00 14.500000
# SDa2.3         3         4   SDa10 23:25  09:00  9.083333
# SDa10.3        3         4    SDa2 23:25  08:30  9.583333
© www.soinside.com 2019 - 2024. All rights reserved.