【问题标题】:A general solution to analyze and plot two data frames with varying lengths?分析和绘制两个不同长度的数据框的通用解决方案?
【发布时间】:2026-01-12 02:00:02
【问题描述】:

你能帮帮我吗?

我正在R 中编写代码来自动化多个网络的空模型分析。首先,代码将多个 TXT matrices 读入 R。其次,它计算每个网络的拓扑度量。第三,它使用空模型将每个网络随机化 N 次。第四,它为原始矩阵的所有随机版本计算相同的拓扑度量。

在第五步也是最后一步,我们的想法是将观察到的分数与随机分数的分布进行比较。首先,通过简单计算有多少随机分数高于或低于观察到的分数,以估计 P 值。其次,通过将随机分数的分布绘制为密度,并添加一条垂直线来显示观察到的分数。

以下是需要分析的data frames 示例:

networks <- paste("network", rep(1:3), sep = "")
randomizations <- seq(1:10)

observed.ex <- data.frame(network = networks,
                          observed = runif(3, min = 0, max = 1))

randomized.ex <- data.frame(network = sort(rep(networks, 10)),
                            randomization = rep(randomizations, 3),
                            randomized = rnorm(length(networks)*
                                                   length(randomizations),
                                               mean = 0.5, sd = 0.1))

在最终分析的第一步中,代码通过简单的计数来估计 P 值。如您所见,我需要为每个网络制作计算调用的副本:

randomized.network1 <- subset(randomized.ex, network == "network1")
sum(randomized.network1$randomized >= observed.ex$observed[1]) /
    length(randomized.network1$randomized)
sum(randomized.network1$randomized <= observed.ex$observed[1]) /
    length(randomized.network1$randomized)

randomized.network2 <- subset(randomized.ex, network == "network2")
sum(randomized.network2$randomized >= observed.ex$observed[2]) /
    length(randomized.network2$randomized)
sum(randomized.network2$randomized <= observed.ex$observed[2]) /
    length(randomized.network2$randomized)

randomized.network3 <- subset(randomized.ex, network == "network3")
sum(randomized.network3$randomized >= observed.ex$observed[3]) /
    length(randomized.network3$randomized)
sum(randomized.network3$randomized <= observed.ex$observed[3]) /
    length(randomized.network3$randomized)

在最后分析的第二步,代码制作密度图。如您所见,我需要为每个网络制作垂直线调用的副本:

ggplot(randomized.ex, aes(randomized)) +
    geom_density() +
    facet_grid(network~.) +
    geom_vline(data=filter(randomized.ex, network == "network1"),
               aes(xintercept = observed.ex$observed[1]), colour = "red") + 
    geom_vline(data=filter(randomized.ex, network == "network2"),
               aes(xintercept = observed.ex$observed[2]), colour = "red") + 
    geom_vline(data=filter(randomized.ex, network == "network3"),
               aes(xintercept = observed.ex$observed[3]), colour = "red") 

有没有办法让这个最终分析更通用,所以无论一开始读取多少个网络,它总是执行相同的计算和绘图?

非常感谢!

【问题讨论】:

    标签: r dataframe matrix p-value density-plot


    【解决方案1】:

    看起来这可以整齐地包装在一个循环遍历每个文件的lapply 中。以下如何为您工作?您还可以传入文件名而不是文件数(目前为 1:3),并在您的 TXT 矩阵中“读取”第一行。

    library(dplyr) #For %>%, group_by, and summarize
    output <- lapply(1:3, function(network_num){
      network <- paste0("network", network_num)
      n_randomizations <- 10
      observed.ex <- runif(1)
      randomized.ex <- rnorm(n_randomizations, mean = 0.5, sd = 0.1)
    
      return(data.frame(network=network, observed=observed.ex, randomized=randomized.ex))
    }) %>% do.call(what = rbind)
    
    output %>%
      group_by(network) %>%
      summarize(p_value=mean(observed>=randomized))
    
    ggplot(output) +
      geom_density(aes(randomized)) +
      facet_grid(network~.) +
      geom_vline(aes(xintercept = observed), col="red")
    

    【讨论】:

    • 非常感谢!它工作得很好。我的代码一开始就将 TXT 文件读入一个列表,然后进行随机化并为观察到的和随机化的矩阵计算选择的网络度量。现在我要将尽可能多的调用转换为 tidyverse 等价物,因此它运行得更快。然后我会将我的代码放在 GitHub 上以帮助其他人。
    • 正如承诺的那样,这里有一个 repo,让任何对相同分析感兴趣的人都可以使用代码:github.com/marmello77/multiple-networks
    最近更新 更多