关注此问题How to divide between groups of rows using dplyr?。
如果我有这个数据框:
id = c("a","a","b","b","c","c")
condition = c(0,1,0,1,0,1)
gene1 = sample(1:100,6)
gene2 = sample(1:100,6)
#...
geneN = sample(1:100,6)
df = data.frame(id,condition,gene1,gene2,geneN)
我希望按ID进行分组,并将条件== 0的行的值与条件== 1的行除以得到:
df[condition == 0,3:5]/ df[condition == 1,3:5]
#
gene1 gene2 geneN
1 0.2187500 0.4946237 0.3750000
3 0.4700000 0.6382979 0.5444444
5 0.7674419 0.5471698 2.3750000
我可以按如下方式使用dplyr:
df %>%
group_by(id) %>%
summarise(gene1 = gene1[condition == 0] / gene1[condition == 1],
gene2 = gene2[condition == 0] / gene2[condition == 1],
geneN = geneN[condition == 0] / geneN[condition == 1])
但我有例如100个变量如下。如何在不必列出所有基因的情况下做到这一点。
id = c("a","a","b","b","c","c")
condition = c(0,1,0,1,0,1)
genes = matrix(1:600,ncol = 100)
df = data.frame(id,condition,genes)
答案 0 :(得分:3)
我们可以使用summarise_at
将相同的操作应用于多列。
library(dplyr)
df2 <- df %>%
group_by(id) %>%
arrange(condition) %>%
summarise_at(vars(-condition), funs(first(.)/last(.))) %>%
ungroup()
df2
# # A tibble: 3 x 4
# id gene1 gene2 geneN
# <fct> <dbl> <dbl> <dbl>
# 1 a 0.524 2.28 0.654
# 2 b 1.65 0.616 1.38
# 3 c 0.578 2.00 2.17
答案 1 :(得分:1)
你可以尝试
df %>%
gather(k,v, -id, -condition) %>%
spread(condition, v) %>%
mutate(ratio=`0`/`1`) %>%
select(id, k, ratio) %>%
spread(k, ratio)
id gene1 gene2 geneN
1 a 0.3670886 0.5955056 1.192982
2 b 0.4767442 1.2222222 0.125000
3 c 18.2000000 2.0909091 6.000000
将您的数据用于set.seed(123)
答案 2 :(得分:0)
如果您的数据集已排序且没有异常,则可以使用purr::map_dfr
:
df[paste0("gene",c(1,2,"N"))] %>% map_dfr(~.x[c(F,T)]/.x[c(T,F)])
# # A tibble: 3 x 3
# gene1 gene2 geneN
# <dbl> <dbl> <dbl>
# 1 0.1764706 1.323944 38.5000000
# 2 0.4895833 0.531250 0.3478261
# 3 0.3278689 2.705882 1.2424242
或其基本R等价物:
as.data.frame(lapply(df[paste0("gene",c(1,2,"N"))],function(x) x[c(F,T)]/x[c(T,F)]))
您可能需要绑定observations
,我跳过此步骤,因为它不在预期的输出中。