【问题标题】:Splitting data and fitting distributions efficiently有效地拆分数据和拟合分布
【发布时间】:2018-07-13 15:39:30
【问题描述】:

对于一个项目,我收到了大量机密的患者级别数据,我需要对其进行拟合分布,以便在模拟模型中使用它。我正在使用 R。

问题是我需要拟合分布以获得至少 288 个独立分布(至少 48 个 6 个变量的子集)的形状/速率数据。该过程在变量之间会略有不同(取决于该变量的分布方式),但我希望能够为每个变量设置一个函数或循环,并为我定义的每个子集生成形状和速率数据。

这方面的一个例子:我需要找到患者子集的住院时间数据。有 48 个患者亚组。我目前这样做的方法是手动过滤数据,然后将它们提取到向量中,然后使用fitdist 将数据拟合到向量中。

即对于伽马分布的变量:

vector1 <- los_data %>%
filter(group == 1, setting == 1, diagnosis == 1)

fitdist(vector1, "gamma")

我对数据科学和数据处理还很陌生,而且我知道一定有比手工更简单的方法来做到这一点!我假设与矩阵有关,但我完全不知道如何最好地进行。

【问题讨论】:

  • 可能您需要一个分组方法los_data %&gt;% group_by(group, setting, diagnosis) %&gt;% summarise(yourfunc(columns)) 请展示一个可重复的小示例和预期输出
  • fitdist 接受一个数字向量,并且您的链正在输出一个数据框(等长向量列表)。

标签: r subset simulation distribution purrr


【解决方案1】:

一种常见的做法是使用split 拆分数据,然后将感兴趣的函数应用于该组。假设这里我们有四列,组、设置、诊断和stay.length。前三个有两个级别。

df <- data.frame(
  group = sample(1:2, 64, TRUE),
  setting  = sample(1:2, 64, TRUE),
  diagnosis  = sample(1:2, 64, TRUE), 
  stay.length = sample(1:5, 64, TRUE)
)
> head(df)
    group setting diagnosis var
1     1       1         1   4
2     1       1         2   5
3     1       1         2   4
4     2       1         2   3
5     1       2         2   3
6     1       1         2   5

执行split,你会得到一个分裂的List

dfl <- split(df$stay.length, list(df$group, df$setting, df$diagnosis))

> head(dfl)
$`1.1.1`
[1] 5 3 4 1 4 5 4 2 1

$`2.1.1`
[1] 5 4 5 4 3 1 5 3 1

$`1.2.1`
[1] 4 2 5 4 5 3 5 3

$`2.2.1`
[1] 2 1 4 3 5 4 4

$`1.1.2`
[1] 5 4 4 4 3 2 4 4 5 1 5 5

$`2.1.2`
[1] 5 4 4 5 3 2 4 5 1 2    

之后,我们可以使用lapply 对列表中的每个组执行任何功能。比如我们可以申请mean

dflm <- lapply(dfl, mean)
> dflm
$`1.1.1`
[1] 3.222222

.
.
.
.

$`2.2.2`
[1] 2.8

在您的情况下,您可以应用fitdist 或任何其他功能。

dfl.fitdist <- lapply(dfl, function(x) fitdist(x, "gamma"))

> dfl
$`1.1.1`
Fitting of the distribution ' gamma ' by maximum likelihood 
Parameters:
  estimate Std. Error
shape  3.38170  2.2831073
rate   1.04056  0.7573495

.
.
.


$`2.2.2`
Fitting of the distribution ' gamma ' by maximum likelihood 
Parameters:
  estimate Std. Error
shape 4.868843  2.5184018
rate  1.549188  0.8441106

【讨论】:

  • 谢谢!这将非常有帮助,但是当我尝试使用 fitdist 时出现错误,它说“数据必须是长度大于 1 的数字向量”。我查看了 fitdist 的代码,错误消息与代码相关联: if(!(is.vector(data) & is.numeric(data) & length(data)>1)) stop("data must是长度大于 1") 的数值向量
  • 我添加了如何使用 lapplyfitdist 作为函数。它在示例中运行良好。您面临的问题的一种可能性是,在拆分后,数据向量的长度为 1。确保拆分后,您有足够的数据来执行 fitdist。您可以使用lapply(dfl, length) 查找列表的长度
【解决方案2】:

好的,您的示例在这里不太可重现,但我认为您想要的答案类似于以下内容:

result <- los_data %>%
group_by(group, setting, diagnosis) %>%
do({
  fit <- fitdist(.$my_column, "gamma")
  data_frame(group=.$group[1], setting=.$setting[1], diagnosis=.$diagnosis[1], fit = list(fit))
}) %>%
ungroup()

这将为您提供所有拟合的数据框,其中包含用于组、设置、诊断的列以及包含每个拟合的列表列。由于它是一个列表列,因此您需要使用双括号来提取单个拟合。示例:

# Get the fit in the first row
result$fit[[1]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多