使用 dplyr::group_by() 对每组进行黄土回归
loess regression on each group with dplyr::group_by()
好吧,我挥舞着我的白旗。
我正在尝试计算数据集上的黄土回归。
我希望 loess 计算一组不同的点,这些点绘制为每组的平滑线。
问题是黄土计算正在逃避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=.))
})
这个完全失败并出现以下错误。
"Error: Results 1, 2, 3, 4 must be data frames, not numeric"
此外,它仍未应用为 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
unique(test$CpG)
[1] "cg25296477" "cg01003813" "cg13176022" "cg26484667"
所以,明确地说,我想对我的数据框中的每个唯一 CpG 进行黄土回归,将结果 "regressed y axis values" 应用到与原始 y 轴值 (Meth) 匹配的列。
我的实际数据集有几千个 CpG,而不仅仅是四个。
https://docs.google.com/spreadsheets/d/1-Wluc9NDFSnOeTwgBw4n0pdPuSlMSTfUVM0GJTiEn_Y/edit?usp=sharing
您可能已经解决了这个问题——但如果没有,这里有一些帮助。
基本上,您需要为预测函数提供一个 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?我记不清了)。此外,这将需要一段时间 运行,因此请测试您的一部分数据以确保其正常工作。
这是使它工作的一种巧妙的 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))
好吧,我挥舞着我的白旗。
我正在尝试计算数据集上的黄土回归。
我希望 loess 计算一组不同的点,这些点绘制为每组的平滑线。
问题是黄土计算正在逃避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=.))
})
这个完全失败并出现以下错误。
"Error: Results 1, 2, 3, 4 must be data frames, not numeric"
此外,它仍未应用为 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
unique(test$CpG) [1] "cg25296477" "cg01003813" "cg13176022" "cg26484667"
所以,明确地说,我想对我的数据框中的每个唯一 CpG 进行黄土回归,将结果 "regressed y axis values" 应用到与原始 y 轴值 (Meth) 匹配的列。
我的实际数据集有几千个 CpG,而不仅仅是四个。
https://docs.google.com/spreadsheets/d/1-Wluc9NDFSnOeTwgBw4n0pdPuSlMSTfUVM0GJTiEn_Y/edit?usp=sharing
您可能已经解决了这个问题——但如果没有,这里有一些帮助。
基本上,您需要为预测函数提供一个 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?我记不清了)。此外,这将需要一段时间 运行,因此请测试您的一部分数据以确保其正常工作。
这是使它工作的一种巧妙的 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))