Создайте столбец тибла (или фрейма данных), который содержит список из длинного формата тибла
У меня есть объекты с разным количеством событий в разное время. В настоящее время он хранится в длинном формате (используя тиблы из библиотеки (tidyverse)):
timing_tbl <- tibble(ID = c(101,101,101,102,102,103,103,103,103),
event_time = c(0,4,8,0,6,0,4,9,12))
Реальные данные содержат тысячи объектов, до 50 или более событий, поэтому я хочу сделать этот процесс максимально эффективным.
Я хотел бы преобразовать это в псевдоширокий формат, где первый столбец - это идентификатор пациента, а второй - список времен события для этого объекта. Я могу сделать это, где второй столбец является столбцом тиблей следующим образом
tmp <- lapply(unique(timing_tbl$ID),
function(x) timing_tbl[timing_tbl$ID == x, "event_time"])
timing_tbl2 <- tibble(unique(timing_tbl$ID),tmp)
> timing_tbl2[1,2]
# A tibble: 1 x 1
tmp
<list>
1 <tibble [3 × 1]>
> timing_tbl2[[1,2]]
# A tibble: 3 x 1
event_time
<dbl>
1 0
2 4.00
3 8.00
Я бы предпочел хранить эти объекты в виде списков, так как затем я хочу найти "расстояние" между каждой парой объектов, используя следующую функцию, и я беспокоюсь, что извлечение вектора из списка добавляет ненужную обработку, замедляя вычисления.
lap_exp2 <- function(x,y,tau) {
exp(-abs(x - y)/tau)
}
distance_lap2 <- function(vec1,vec2,tau) {
## vec1 is first list of event times
## vec2 is second list of event times
## tau is the decay parameter
0.5*(sum(outer(vec1,vec1,FUN=lap_exp2, tau = tau)) +
sum(outer(vec2,vec2,FUN=lap_exp2, tau = tau))
) -
sum(outer(vec1,vec2,FUN=lap_exp2, tau = tau))
}
distance_lap2(timing_tbl2[[1,2]]$event_time,timing_tbl2[[2,2]]$event_time,2)
[1] 0.8995764
Если я попытаюсь извлечь список вместо таблицы, используя [[
tmp <- lapply(unique(timing_tbl$ID),
function(x) timing_tbl[[timing_tbl$ID == x, "event_time"]])
Я получаю следующую ошибку, которая имеет смысл
Error in col[[i, exact = exact]] : attempt to select more than one element in vectorIndex
Есть ли достаточно простой способ извлечь столбец из длинного фрагмента в виде списка и сохранить его в новом фрагменте? Это даже правильный путь?
1 ответ
Я нашел использование tidyr::nest
хороший способ создать "столбцы списка", я думаю, вы можете использовать его (особенно для заполнения данных в виде временных рядов). Надеюсь, что следующее поможет!
library(dplyr)
library(tidyr)
library(purrr)
timing_tbl <- tibble(ID = c(101,101,101,102,102,103,103,103,103),
event_time = c(0,4,8,0,6,0,4,9,12))
ID_times <-
timing_tbl %>%
group_by(ID) %>%
nest(.key = "times_df") %>%
split(.$ID) %>%
map(~ .$times_df %>% unlist(use.names = F))
# > ID_times
# $`101`
# [1] 0 4 8
# $`102`
# [1] 0 6
# $`103`
# [1] 0 4 9 12
dists_long <-
names(ID_times) %>%
expand.grid(IDx = ., IDy = .) %>%
filter(IDx != IDy) %>%
rowwise() %>%
mutate(dist = distance_lap2(vec1 = ID_times[[IDx]], vec2 = ID_times[[IDy]], tau = 2))
# # A tibble: 6 x 3
# IDx IDy dist
# <fct> <fct> <dbl>
# 1 102 101 0.900
# 2 103 101 0.981
# 3 101 102 0.900
# 4 103 102 1.68
# 5 101 103 0.981
# 6 102 103 1.68