我正在尝试从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
降雨数据作为行。我想对每个mmky1lag
的数据应用modifiedmk
包中的Station
方法,并在R中生成一个包含两列的汇总表:
例如,我可以使用生成的mmky1lag
对所有的Rainfall数据运行mmky1lag(as.vector(data$Rainfall))
方法
> 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中,我将对Station
进行分组,然后应用该方法。但是我不确定如何在R中做到这一点。
然后按站进行分组后,我想要一个包含上述两列信息的汇总表。
答案 0 :(得分:2)
如果要将mmky1lag
函数按组应用于数据帧(在这种情况下为station
),可以考虑多种方法。
首先,您可以使用aggregate
:
library(modifiedmk)
mktests <- aggregate(Rainfall ~ Station, data = data, FUN = mmky1lag)
这将采用Rainfall
组度量Station
的公式。您所有的结果都将以矩阵形式返回,其中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_by
对Station
进行分组,然后使用group_map
将mmky1lag
函数应用于分组的元素。需要setNames
才能将Station
的值添加回结果中,然后需要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
如果您希望Station
的百分比为p <.05,可以这样做:
sum(mktests$`new P-value` < .05) / nrow(mktests)
在这种情况下,它为零,因为根据new P-value
,它们都不是有效的。
可以计算Sen's slope
的平均值:
mean(mktests$`Sen's slope`)
4.45125
我不确定您的示例数据是否会得出不同的结果(因为您建议将结果分成两列)。请让我知道这是否是您的想法。
答案 1 :(得分:2)
您可以尝试在基本R中做类似的事情。
首先,您可以将数据作为列表,每个元素都是一个Station
:
data_list <- split(data,data$Station)
然后您可以使用lapply()
,引用the doc:
lapply返回一个与X长度相同的列表,其中每个元素 是将FUN应用于X的相应元素的结果。
library(modifiedmk)
stat_list <- lapply(data_list, function(x) mmky1lag(x$Rainfall))
现在,您可以输入data.frame
,然后计算所需的内容。
您可以使用do.call()
将rbind()
应用于列表,并将其放入data.frame()
中。通常,我更喜欢使用列名而不是索引,但这是主观的。
来自the doc rbind()
:
采用向量,矩阵或数据帧参数的序列并合并 分别按列或行。这些是具有 其他R类的方法。
来自the doc 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。如果定义了它,则可能会得到更适合您要求的结果。
答案 2 :(得分:1)
这接近吗?该百分比将为零,因为所有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
答案 3 :(得分:0)
如果使用tidyverse,则很容易进行类似熊猫的语法。
{"accountingCurrency":"USD","address1":"test address","billedCurrency":"EUR","billedRecurringPrice":"0.00","bin":"444444","cardType":"VISA","city":"testcity","country":"FR","initialPeriod":"30","lastName":"test","timestamp":"2020-11-12 06:05:49","username":"llllll","threeDSecure":"NOT_APPLICABLE"}