[英]How to apply custom function to multiple columns in R and store many dataframes using loops
我有大量(實際上很多)來自實驗室火災實驗的溫度數據,這些數據觀察了距火源不同距離的溫度分布。 這些輸出文件看起來像這樣:
時間序列 | 溫度_1 | 溫度_2 | 溫度_3 | 溫度_4 |
---|---|---|---|---|
0 | 977.1874 | 843.6411 | 962.6087 | 720.8003 |
0.002 | 973.9924 | 840.3609 | 960.572 | 724.4845 |
0.004 | 970.8031 | 837.1157 | 957.9192 | 727.7389 |
但有更多的溫度測量和時間序列。 我需要做的是為大約 200 個不同的數據文件中的每一個捕獲數據框中每一列的平均值、最小值、最大值和間歇性。 前三個是我使用 summarize_all(df, mean) 命令計算出來的。 然而,間歇性需要使用自定義函數執行與此類似的操作,在本例中是找到大於 500 的總溫度值的百分比。因此在 Excel 中計算這個我會使用類似的東西
=COUNTIF(B2:B46001, ">500")/COUNT(B2:B46001)
我將 >500 的值的計數除以每列中所有值的計數。 作為一個 Excel 人,我想知道在 R 中執行此操作的最佳方法是什么? 否則,遍歷每個文件是一個漫長的手動過程......
此外,如果有人對如何使用某種循環在多個數據幀上運行它有任何建議,以便我最終得到一個包含我需要的所有值的完整數據幀,那會更好。 每個數據框都有一個實驗標識符#(從 C2700 到 C2890),我不確定是否有辦法循環遍歷每個數據框並將結果組合成一個大數據框...
如前所述,我已經能夠總結均值、最小值和最大值,但我對如何使用自定義函數進行總結感到困惑。 目前我有這樣簡單的事情:
stats_mean <- summarize_all(df1, mean)
stats_min <- summarize_all(df1, min)
stats_max <- summarize_all(df1, max)
stats_intermit <- ???
stats <- rbind(stats_mean, stats_max, stats_min, stats_intermit)
我對循環的了解還不夠多,無法輕松確定為多個數據幀運行此循環的最佳方法,因此也將不勝感激任何建議!
將您的 data.frames 放入列表中並使用lapply
遍歷每個。 至於你的間歇性問題,你可以嘗試一些類似的方法
xy <- data.frame(matrix(1:9, nrow = 3))
apply(xy[, 2:3], MARGIN = 2, FUN = function(x) sum(x > 5) / length(x) )
X2 X3
0.3333333 1.0000000
一次性嘗試所有這些組合(使用bind_rows
)。 我們可以使用across
運行多個函數,其中命名的函數列表是查看事物的簡單方法:
(僅供參考:我更改了quux
中的值,以便我們至少有一個不超過 500 的值。)
quux <- structure(list(Time_series = c(0, 0.002, 0.004), Temperature_1 = c(977.1874, 473, 970.8031), Temperature_2 = c(843.6411, 840.3609, 837.1157), Temperature_3 = c(962.6087, 960.572, 957.9192), Temperature_4 = c(720.8003, 724.4845, 727.7389)), row.names = c(NA, -3L), class = "data.frame")
quuxs <- list(A=quux, B=quux, C=quux)
library(dplyr)
bind_rows(quuxs, .id = "id") %>%
group_by(id) %>%
summarize(across(everything(), list(
mean = ~ mean(.), min = ~ min(.), max = ~ max(.),
interm = ~ mean(. > 500)))
)
# # A tibble: 3 × 21
# id Time_seri…¹ Time_…² Time_…³ Time_…⁴ Tempe…⁵ Tempe…⁶ Tempe…⁷ Tempe…⁸ Tempe…⁹ Tempe…˟ Tempe…˟ Tempe…˟ Tempe…˟ Tempe…˟ Tempe…˟
# <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 A 0.002 0 0.004 0 807. 473 977. 0.667 840. 837. 844. 1 960. 958. 963.
# 2 B 0.002 0 0.004 0 807. 473 977. 0.667 840. 837. 844. 1 960. 958. 963.
# 3 C 0.002 0 0.004 0 807. 473 977. 0.667 840. 837. 844. 1 960. 958. 963.
# # … with 5 more variables: Temperature_3_interm <dbl>, Temperature_4_mean <dbl>, Temperature_4_min <dbl>, Temperature_4_max <dbl>,
# # Temperature_4_interm <dbl>, and abbreviated variable names ¹Time_series_mean, ²Time_series_min, ³Time_series_max,
# # ⁴Time_series_interm, ⁵Temperature_1_mean, ⁶Temperature_1_min, ⁷Temperature_1_max, ⁸Temperature_1_interm, ⁹Temperature_2_mean,
# # ˟Temperature_2_min, ˟Temperature_2_max, ˟Temperature_2_interm, ˟Temperature_3_mean, ˟Temperature_3_min, ˟Temperature_3_max
(您可能希望/需要為每個最小/最大/求和函數包含na.rm=TRUE
。)
不可否認,這有點吵,但名字很清楚:
... %>% names()
# names
# [1] "id" "Time_series_mean" "Time_series_min" "Time_series_max" "Time_series_interm"
# [6] "Temperature_1_mean" "Temperature_1_min" "Temperature_1_max" "Temperature_1_interm" "Temperature_2_mean"
# [11] "Temperature_2_min" "Temperature_2_max" "Temperature_2_interm" "Temperature_3_mean" "Temperature_3_min"
# [16] "Temperature_3_max" "Temperature_3_interm" "Temperature_4_mean" "Temperature_4_min" "Temperature_4_max"
# [21] "Temperature_4_interm"
如果你想讓它更緊湊一點,也許我們可以調整它:
library(tidyr) # pivot_longer
bind_rows(quuxs, .id = "id") %>%
group_by(id) %>%
summarize(across(everything(), list(mean = ~ mean(.), min = ~ min(.), max = ~ max(.), interm = ~ mean(. > 500)))) %>%
pivot_longer(-id, names_pattern = "(.*)_([^_]*)$", names_to = c("temp", ".value"))
# # A tibble: 15 × 6
# id temp mean min max interm
# <chr> <chr> <dbl> <dbl> <dbl> <dbl>
# 1 A Time_series 0.002 0 0.004 0
# 2 A Temperature_1 807. 473 977. 0.667
# 3 A Temperature_2 840. 837. 844. 1
# 4 A Temperature_3 960. 958. 963. 1
# 5 A Temperature_4 724. 721. 728. 1
# 6 B Time_series 0.002 0 0.004 0
# 7 B Temperature_1 807. 473 977. 0.667
# 8 B Temperature_2 840. 837. 844. 1
# 9 B Temperature_3 960. 958. 963. 1
# 10 B Temperature_4 724. 721. 728. 1
# 11 C Time_series 0.002 0 0.004 0
# 12 C Temperature_1 807. 473 977. 0.667
# 13 C Temperature_2 840. 837. 844. 1
# 14 C Temperature_3 960. 958. 963. 1
# 15 C Temperature_4 724. 721. 728. 1
或者,如果您更喜歡轉置格式,
bind_rows(quuxs, .id = "id") %>%
group_by(id) %>%
summarize(across(everything(), list(mean = ~ mean(.), min = ~ min(.), max = ~ max(.), interm = ~ mean(. > 500)))) %>%
pivot_longer(-id, names_pattern = "(.*)_([^_]*)$", names_to = c(".value", "stat"))
# # A tibble: 12 × 7
# id stat Time_series Temperature_1 Temperature_2 Temperature_3 Temperature_4
# <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 A mean 0.002 807. 840. 960. 724.
# 2 A min 0 473 837. 958. 721.
# 3 A max 0.004 977. 844. 963. 728.
# 4 A interm 0 0.667 1 1 1
# 5 B mean 0.002 807. 840. 960. 724.
# 6 B min 0 473 837. 958. 721.
# 7 B max 0.004 977. 844. 963. 728.
# 8 B interm 0 0.667 1 1 1
# 9 C mean 0.002 807. 840. 960. 724.
# 10 C min 0 473 837. 958. 721.
# 11 C max 0.004 977. 844. 963. 728.
# 12 C interm 0 0.667 1 1 1
(唯一的變化是names_to=
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.