我有一個問題,我可以用蠻力解決,但想學習一種更簡潔的方法,我認為這需要從串列串列中呼叫觀察。
我正在跟蹤表面上的粒子,其中每個觀察都是給定時間的特定粒子,以及實驗干預。
我已經制作了一個particle.ids串列,這些s 已經移動了給定的距離(00 毫米、1 毫米、3 毫米、5 毫米等),并想看看每個粒子到達那個距離需要多長時間。
library(tidyverse)
library(here)
load(here("outputs", "master.muc.RData")) #all particles with all data
load(here("outputs", "max.disp.RData")) #one observation per particle, using slice_max(displacement)
#links below
鏈接到 master.muc,其中包括所有粒子觀測https://www.dropbox.com/s/77h4aajfmfvpeb5/master.muc.RData?dl=0
鏈接到 max.disp,基于最大位移的每個粒子的單個觀察https://www.dropbox.com/s/y6qmt85wskmj9mg/max.disp.RData?dl=0
這是我創建距離串列的方法。我相信這可以簡化,我很高興收到反饋。我也試過這個作為 list() 并使用 select() 而不是 pull()
disp.00 <- max.disp %>%
filter(displacement < 0.03) %>%
pull(particle.id)
disp.03 <- max.disp %>%
filter(displacement >= 0.03) %>%
pull(particle.id)
disp.05 <- max.disp %>%
filter(displacement >= 0.05) %>%
pull(particle.id)
disp.10 <- max.disp %>%
filter(displacement >= 0.10) %>%
pull(particle.id)
disp.15 <- max.disp %>%
filter(displacement >= 0.15) %>%
pull(particle.id)
disp.20 <- max.disp %>%
filter(displacement >= 0.20) %>%
pull(particle.id)
disp.25 <- max.disp %>%
filter(displacement >= 0.25) %>%
pull(particle.id)
disp.30 <- max.disp %>%
filter(displacement >= 0.30) %>%
pull(particle.id)
disp.50 <- max.disp %>%
filter(displacement >= 0.50) %>%
pull(particle.id)
disp.75 <- max.disp %>%
filter(displacement >= 0.75) %>%
pull(particle.id)
disp.99 <- max.disp %>%
filter(displacement > 0.99) %>%
pull(particle.id)
為資料填充創建一個小標題
particle.displacement <- master.muc %>% select(particle.id) %>% unique()
particle.displacement <- particle.displacement %>% add_column(disp.00 = NA,
disp.03 = NA,
disp.05 = NA,
disp.10 = NA,
disp.15 = NA,
disp.20 = NA,
disp.25 = NA,
disp.30 = NA,
disp.50 = NA,
disp.75 = NA,
disp.99 = NA)
time.min.part.disp <- particle.displacement
time.max.part.disp <- particle.displacement
然后我想dt為該串列中出現的每個粒子添加最小經過時間 ?t, s,未出現在每個串列中的粒子將保留為 NA
displacements <- c(disp.00, disp.03, disp.05, disp.10, disp.15, disp.20, disp.25, disp.30, disp.50, disp.75, disp.99) #i've tried this as a list as well.
for(j in 1:length(displacements)){
#j <- 8
dt.min <- master.muc %>%
filter(particle.id %in% paste(displacements[j])) %>% #this command works if i call the list directly, for example: %in% disp.05, but not as a loop
slice_min(dt) %>%
select(particle.id, dt)
dt.max <- master.muc %>% group_by(particle.id) %>%
filter(particle.id %in% displacements[j]) %>%
slice_max(dt) %>%
select(particle.id, dt)
time.min.part.disp <- left_join(time.min.part.disp, dt.min, by = particle.id)
time.max.part.disp <- left_join(time.max.part.disp, dt.max, by = particle.id)
}
我打算為每個串列手動執行此操作,但我寧愿不冒一些手動錯誤的風險,也希望能學到一些東西。
d.00.min <- master.muc %>% group_by(particle.id) %>%
filter(particle.id %in% disp.00) %>%
slice_min(dt) %>%
select(particle.id, dt)
d.00.max <- master.muc %>% group_by(particle.id) %>%
filter(particle.id %in% disp.00) %>%
slice_max(dt) %>%
select(particle.id, dt)
謝謝您的幫助!
uj5u.com熱心網友回復:
您可以創建一個表,每行包含一個粒子或一個粒子置換組合,并用于mutate計算例如被置換至少那么多的 id。以下是一些啟發靈感的代碼:
library(tidyverse)
load("master.muc.RData")
load("max.disp.RData")
displacements <- c(0.03, 0.05, 0.10, 0.15, 0.20, 0.25, 0.30, 0.75, 0.99)
particle_ids <- master.muc %>% pull(particle.id) %>% unique()
displaced_particles <-
tibble(displacement = displacements) %>%
mutate(
particle.id = displacement %>% map(~ {
max.disp %>%
filter(displacement >= .x) %>%
pull(particle.id)
})
) %>%
unnest(particle.id)
displaced_particles
#> # A tibble: 119,081 x 2
#> displacement particle.id
#> <dbl> <chr>
#> 1 0.03 100-135-001-0
#> 2 0.03 100-135-001-1
#> 3 0.03 100-135-001-10
#> 4 0.03 100-135-001-101
#> 5 0.03 100-135-001-102
#> 6 0.03 100-135-001-103
#> 7 0.03 100-135-001-104
#> 8 0.03 100-135-001-105
#> 9 0.03 100-135-001-106
#> 10 0.03 100-135-001-106
#> # … with 119,071 more rows
particle_durations <-
master.muc %>%
group_by(particle.id) %>%
summarise(
min_elapsed_time = min(dt),
max_elapsed_time = max(dt)
)
particle_durations
#> # A tibble: 14,594 x 3
#> particle.id min_elapsed_time max_elapsed_time
#> <chr> <dbl> <dbl>
#> 1 100-135-001-0 0 21.9
#> 2 100-135-001-1 0 33
#> 3 100-135-001-10 0 22.8
#> 4 100-135-001-101 0 39.9
#> 5 100-135-001-102 0 20.1
#> 6 100-135-001-103 0 23.4
#> 7 100-135-001-104 0 23.1
#> 8 100-135-001-105 0 25.5
#> 9 100-135-001-106 0 137.
#> 10 100-135-001-108 0 31.5
#> # … with 14,584 more rows
particle_durations %>%
left_join(displaced_particles)
#> Joining, by = "particle.id"
#> # A tibble: 123,303 x 4
#> particle.id min_elapsed_time max_elapsed_time displacement
#> <chr> <dbl> <dbl> <dbl>
#> 1 100-135-001-0 0 21.9 0.03
#> 2 100-135-001-0 0 21.9 0.05
#> 3 100-135-001-0 0 21.9 0.1
#> 4 100-135-001-0 0 21.9 0.15
#> 5 100-135-001-0 0 21.9 0.2
#> 6 100-135-001-0 0 21.9 0.25
#> 7 100-135-001-1 0 33 0.03
#> 8 100-135-001-1 0 33 0.05
#> 9 100-135-001-1 0 33 0.1
#> 10 100-135-001-1 0 33 0.15
#> # … with 123,293 more rows
displaced_particles %>%
nest(particle.id) %>%
mutate(
data = data %>% map(~ {
master.muc %>%
# filter before group_by is much faster
filter(particle.id %in% .x$particle.id) %>%
group_by(particle.id) %>%
slice_min(dt) %>%
select(particle.id, dt)
})
) %>%
unnest(data)
#> Warning: All elements of `...` must be named.
#> Did you want `data = c(particle.id)`?
#> # A tibble: 57,666 x 3
#> displacement particle.id dt
#> <dbl> <chr> <dbl>
#> 1 0.03 100-135-001-0 0
#> 2 0.03 100-135-001-1 0
#> 3 0.03 100-135-001-10 0
#> 4 0.03 100-135-001-101 0
#> 5 0.03 100-135-001-102 0
#> 6 0.03 100-135-001-103 0
#> 7 0.03 100-135-001-104 0
#> 8 0.03 100-135-001-105 0
#> 9 0.03 100-135-001-106 0
#> 10 0.03 100-135-001-108 0
#> # … with 57,656 more rows
由reprex 包(v2.0.1)于 2021 年 12 月 14 日創建
您可以使用nest和unnest將表格拆分為行組。通常,最好有 3NF 標準化長表,例如displaced_particles每個單元格只有一個數字。這更容易例如連接表格以將來自不同表格列的相同粒子的屬性收集在一起。
由于檔案中只有一個物件max.disp.RData,您應該將它們保存為 RDS。還要考慮到其他人可能不會使用 R 進行資料分析,因此有諸如羽毛甚至 CSV 之類的檔案格式,使您的資料與其他工具更加兼容。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/380663.html
