使用dplyr :: group_by()对每个组进行黄土回归

问题描述 投票:3回答:2

好吧,我挥舞着白旗。

我正在尝试在我的数据集上计算黄土回归。

我想让黄土计算一组不同的点,这些点绘制成每组的平滑线。

问题是黄土计算是逃避dplyr::group_by函数,所以黄土回归是在整个数据集上计算的。

互联网搜索让我相信这是因为dplyr::group_by并不打算以这种方式工作。

我无法弄清楚如何在每个组的基础上进行这项工作。

以下是我尝试失败的一些例子。

test2 <- test %>% 
  group_by(CpG) %>% 
  dplyr::arrange(AVGMOrder) %>% 
  do(broom::tidy(predict(loess(Meth ~ AVGMOrder, span = .85, data=.))))

> test2
# A tibble: 136 x 2
# Groups:   CpG [4]
   CpG            x
   <chr>      <dbl>
 1 cg01003813 0.781
 2 cg01003813 0.793
 3 cg01003813 0.805
 4 cg01003813 0.816
 5 cg01003813 0.829
 6 cg01003813 0.841
 7 cg01003813 0.854
 8 cg01003813 0.866
 9 cg01003813 0.878
10 cg01003813 0.893

这个可行,但我无法弄清楚如何将结果应用于原始数据帧中的列。我想要的结果是第x列。如果我在一个单独的行中将x作为列应用,我会遇到问题因为我之前调用了dplyr::arrange

test2 <- test %>% 
  group_by(CpG) %>% 
  dplyr::arrange(AVGMOrder) %>% 
  dplyr::do({
    predict(loess(Meth ~ AVGMOrder, span = .85, data=.))
  })

这个只是失败,出现以下错误。

“错误:结果1,2,3,4必须是数据框,而不是数字”

此外,它仍未作为dplyr::mutate的新列应用

fems <- fems %>% 
  group_by(CpG) %>% 
  dplyr::arrange(AVGMOrder) %>% 
  dplyr::mutate(Loess = predict(loess(Meth ~ AVGMOrder, span = .5, data=.)))

这是我的第一次尝试,大部分类似于我想做的事情。问题是这个对整个数据帧执行黄土预测,而不是对每个CpG组执行黄土预测。

我真的被困在这里了。我在网上看到purr包可能会有所帮助,但我无法搞清楚。

数据看起来像这样:

> head(test)
    X geneID        CpG                                        CellLine       Meth AVGMOrder neworder Group SmoothMeth
1  40     XG cg25296477 iPS__HDF51IPS14_passage27_Female____165.592.1.2 0.81107210         1        1     5  0.7808767
2  94     XG cg01003813 iPS__HDF51IPS14_passage27_Female____165.592.1.2 0.97052120         1        1     5  0.7927130
3 148     XG cg13176022 iPS__HDF51IPS14_passage27_Female____165.592.1.2 0.06900448         1        1     5  0.8045080
4 202     XG cg26484667 iPS__HDF51IPS14_passage27_Female____165.592.1.2 0.84077890         1        1     5  0.8163997
5  27     XG cg25296477  iPS__HDF51IPS6_passage33_Female____157.647.1.2 0.81623880         2        2     3  0.8285259
6  81     XG cg01003813  iPS__HDF51IPS6_passage33_Female____157.647.1.2 0.95569240         2        2     3  0.8409501

独特的(测试$ CpG)[1]“cg25296477”“cg01003813”“cg13176022”“cg26484667”

因此,为了清楚起见,我想对我的数据帧中的每个唯一CpG进行黄土回归,将得到的“回归的y轴值”应用于与原始y轴值(Meth)匹配的列。

我的实际数据集有几千个CpG,而不仅仅是四个。

https://docs.google.com/spreadsheets/d/1-Wluc9NDFSnOeTwgBw4n0pdPuSlMSTfUVM0GJTiEn_Y/edit?usp=sharing

r dplyr purrr loess broom
2个回答
1
投票

你可能已经想到了这一点 - 但如果没有,这里有一些帮助。

基本上,您需要为预测函数提供您想要预测的值的data.frame(向量可能也可以,但我没有尝试)。

所以对于你的情况:

fems <- fems %>% 
  group_by(CpG) %>% 
  arrange(CpG, AVGMOrder) %>% 
  mutate(Loess = predict(loess(Meth ~ AVGMOrder, span = .5, data=.),
    data.frame(AVGMOrder = seq(min(AVGMOrder), max(AVGMOrder), 1))))

注意,黄土需要运行最少数量的观测值(~4?我记不清楚了)。此外,这将需要一段时间来运行所有测试与一片数据,以确保它正常工作。


1
投票

这是一个简洁的Tidyverse方式,使其工作:

library(dplyr)
library(tidyr)
library(purrr)
library(ggplot2)

models <- fems %>%
        tidyr::nest(-CpG) %>%
        dplyr::mutate(
                # Perform loess calculation on each CpG group
                m = purrr::map(data, loess,
                               formula = Meth ~ AVGMOrder, span = .5),
                # Retrieve the fitted values from each model
                fitted = purrr::map(m, `[[`, "fitted")
        )

# Apply fitted y's as a new column
results <- models %>%
        dplyr::select(-m) %>%
        tidyr::unnest()

# Plot with loess line for each group
ggplot(results, aes(x = AVGMOrder, y = Meth, group = CpG, colour = CpG)) +
        geom_point() +
        geom_line(aes(y = fitted))

This is what the output looks like

© www.soinside.com 2019 - 2024. All rights reserved.