簡體   English   中英

使用來自包 `modifiedmk` 的統計信息在 R 中創建匯總表

[英]Create summary table in R using statistics from package `modifiedmk`

我正在嘗試從 R 中的modifiedmk包中運行一個函數。

install.packages('modifiedmk')
library(modifiedmk)

我有一個數據框data ,我使用以下內容生成:

Station <- c('APT','APT', 'APT','APT', 'APT', 'APT', 'APT','APT', 'APT','APT','APT','APT',
              'AF','AF', 'AF','AF','AF','AF','AF','AF','AF',
             'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL', 'EL',
             'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS', 'GFS'
              )
Rainfall <- c(375.3, 263.3, 399.2, 242.6, 847.6, 276.5, 712.8, 366.3, 188.6, 478.4, 539, 682.5,
            520.7, 1337.8, 524, 908.4,748.5,411.8, 772.4,978.5,983,
            732.4, 788.6, 567.1, 576, 931.6, 727.2, 1079.3, 902.8,493.4,  630.7, 784.1,660.2, 531.3, 487.1,798.4,
            1064.1,  590.3, 1011.2, 1037.1,  1398.4, 1153.6,994.1,  1100.2,743.7,637.4, 792.2, 891.9,880.9, 670, 920.2,681.4)
Year <- c('1957','1958','1959','1960','1961','1962','1963','1964','1965','1966','1967','1968',
                  '1960','1961','1962','1963','1964','1965','1966','1967','1968',
                  '1957','1958','1959','1960','1961','1962','1963','1964','1965','1966','1967','1968','1969','1970','1971',
                  '1964','1965','1966','1967','1968','1969','1970','1971','1972','1973','1974','1975','1976','1977','1978','1979')
length(Year)
data<-data.frame(Year, Station, Rainfall)

我有四個降雨數據Stations作為數據框中的行。 我想在每個數據Station上應用modifiedmk包中的mmky1lag方法,並在 R 中生成一個包含兩列的匯總表:

  1. 具有顯着趨勢的站點百分比,其中 p < 0.05
  2. 平均森斜率

例如,我可以使用mmky1lag(as.vector(data$Rainfall))在所有降雨數據上運行mmky1lag方法,它產生

> mmky1lag(as.vector(data$Rainfall))
Corrected Zc  new P-value         N/N*   Original Z  old P.value 
3.332353e+00 8.611480e-04 1.297360e+00 3.795608e+00 1.472822e-04 
         Tau  Sen's slope old.variance new.variance 
3.634992e-01 9.092857e+00 1.605933e+04 2.083474e+04

我對其中兩個輸出感興趣:

第 1 列:

# Get percent of stations with significant trends where p < 0.05
mmky1lag(as.vector(data$Rainfall))[2] < 0.05

和第 2 列:

# Make another column that is the mean Sen's slope
mmky1lag(as.vector(data$Rainfall))[7] 

但是,如何在data上應用此方法,從而為每個單獨的Station獲得結果? 在python中,我會groupby Station然后應用該方法。 但我不確定如何在 R 中做到這一點。

然后按站分組后,我想要一個包含上述兩列信息的匯總表。

如果您想按組(在本例中為station )將mmky1lag函數應用於數據幀,則需要考慮多種方法。

首先,您可以使用aggregate

library(modifiedmk)

mktests <- aggregate(Rainfall ~ Station, data = data, FUN = mmky1lag)

這將采用按Station組的Rainfall度量的公式。 您的所有結果都將在矩陣中返回,MK 測試參數位於單列中。

另一種方法可能是使用data.table包。

library(data.table)

mktests <- as.data.table(data)[, as.list(mmky1lag(Rainfall)), by = Station]

這將從mmky1lag獲取結果並將其放入列表,然后轉換為數據表。 選項by將允許您通過Station執行此操作。

第三種方法可能是使用dplyr包。

library(dplyr)

mktests <- data %>%
  group_by(Station) %>%
  group_map(~mmky1lag(.x$Rainfall)) %>%
  setNames(unique(sort(data$Station))) %>%
  bind_rows(.id = "Station")

這使用group_byStation分組,然后group_mapmmky1lag函數應用於分組元素。 需要setNamesStation值添加回結果,然后bind_rows將結果列表轉換為數據框。

結果(使用data.table解決方案)應該如下所示(其他方法應該類似):

R> mktests
   Station Corrected Zc new P-value      N/N* Original Z old P.value        Tau Sen's slope old.variance new.variance
1:     APT    1.2801214   0.2005025 0.4849366  0.8914431   0.3726915  0.2121212    17.32083     212.6667    103.12986
2:      AF    1.2424858   0.2140574 0.5703144  0.9383149   0.3480826  0.2777778    29.73750      92.0000     52.46892
3:      EL   -0.7452428   0.4561249 1.1288325 -0.7917947   0.4284804 -0.1619048    -9.60000     408.3333    460.93994
4:     GFS   -1.3242038   0.1854354 1.4160741 -1.5757881   0.1150746 -0.3000000   -19.65333     493.3333    698.59657

如果您想要 p < .05 的Station百分比,您可以執行以下操作:

sum(mktests$`new P-value` < .05) / nrow(mktests)

在這種情況下,它為零,因為基於new P-value ,它們都不顯着。

可以計算Sen's slope的平均值:

mean(mktests$`Sen's slope`)
4.45125

我不確定您是否預期示例數據會產生不同的結果(正如您建議將結果放入 2 列)。 請讓我知道這是否是您的想法。

你可以嘗試在基礎 R 中做這樣的事情。
首先,您可以將數據作為列表,每個元素都是一個Station

data_list <- split(data,data$Station)

然后你可以使用lapply() ,引用自doc

lapply 返回一個與 X 長度相同的列表,其中的每個元素都是將 FUN 應用於 X 的對應元素的結果。

library(modifiedmk)
stat_list <- lapply(data_list, function(x) mmky1lag(x$Rainfall))

現在,您可以將作為data.frame為例,然后計算您需要的內容。 您可以使用do.call()rbind()應用於列表,並將其放入data.frame() 通常我更喜歡使用列的名稱而不是它們的索引,但這是主觀的。
文檔rbind()

取一系列向量、矩陣或數據幀參數,並分別按列或行組合。 這些是具有其他 R 類方法的通用函數。

文檔do.call()

do.call 從名稱或函數以及要傳遞給它的參數列表構造並執行函數調用。

stat_df <- data.frame(do.call(rbind, stat_list))

現在您可以輕松計算您需要的內容:

# percentage of the < 0.05 p-values
# here you calculate the number of row of the subset of interest of the
# df / number of row of the dataset.
nrow(stat_df[stat_df$new.P.value < 0.05,])/nrow(stat_df)*100
[1] 0

# Or if you want a prettier result printed:
library(formattable)
percent(nrow(stat_df[stat_df$new.P.value < 0.05,])/nrow(stat_df))
[1] 0.00%

# the mean of Sen.s.slope
mean(stat_df$Sen.s.slope)
[1] 4.45125

另外,我不明白你想要的輸出,它被寫成 Column1 和 Column2。 如果您定義它,就有可能得到更符合您要求的結果。

這接近嗎? 百分比將為零,因為所有 p 值都大於 5%。 您需要在循環中添加< 0.05才能在數據框中獲得真/假值。

results <- data.frame(matrix(NA, 4, 3))
colnames(results) <- c('station', 'p-val', 'Sen-slope')
for(ii in seq_along(unique(Station))){
  i <- unique(Station)[ii]
  results[ii, 1] <- i
  results[ii, 2] <- mmky1lag(as.vector(data$Rainfall[data$Station %in% i]))[2]
  results[ii, 3] <- mmky1lag(as.vector(data$Rainfall[data$Station %in% i]))[7]
}

> results
  station     p-val Sen-slope
1     APT 0.2005025  17.32083
2      AF 0.2140574  29.73750
3      EL 0.4561249  -9.60000
4     GFS 0.1854354 -19.65333

如果您使用 tidyverse,則很容易執行類似 Pandas 的語法。

# Importing tidyverse
library(tidyverse)

# Calculating grouped values
data %>%
  group_by(Station) %>%
  summarise('p-value' = mmky1lag(Rainfall)[2]<0.05, "Sen's slope" = mmky1lag(Rainfall)[7])

# Output
Station p.value Sen.s.slope
AF      FALSE    29.73750
APT     FALSE    17.32083
EL      FALSE    -9.60000
GFS     FALSE   -19.65333

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM