如何通过将现有行的值与 R dplyr 组合来向数据框添加行
How to add rows to dataframe by combining values of already existing rows with R dplyr
我有以下table,我想修改:
type
position
ratio
number
percentage
DNA
intergenic
0.00026933362
225173
40.757876065
DNA
intragenic
0.00021799943
41250
7.466536342
LINE
intergenic
0.00027633335
48619
8.800376494
LINE
intragenic
0.00031015097
9578
1.733684487
我想添加包含以下修改的行:
类型:如果值“类型”在两行之间相同(在我的情况下总是如此),请将其再次添加到列“类型”的单独行中。
位置:将值从 intergenic/intragenic 更改为 "genome" if (1)
比率:比率值将是根据相同类型值的基因间行和基因内行的比率计算的加权平均值:
((number_intragenic * ratio_intragenic) + (number_intergenic * ratio_intergenic))/(number_intragenic + number_intergenic)
number:相同类型的数字值之和:sum(number_intergenic + number_intragenic)
相同类型的百分比值之和:sum(percentage_intergenic + percentage_intragenic)
我的问题是我不知道如何通过对现有行进行特定计算来向数据框添加行。在 dplyr 中使用 mutate 添加列很容易。我如何为行执行此操作?
如果解决方案在 dplyr 中提供,我会更喜欢。
编辑:加权平均值的公式是错误的。我在公式的以下部分添加了一个 + 号而不是 * 号:(number_intergenic + ratio_intergenic)。现在已经修复了。
献给亲爱的@akrun ,是他教会了我如何做到这一点:
library(dplyr)
library(purrr)
library(tibble)
df %>%
group_split(type) %>%
map_dfr(~ add_row(.x, type = first(.x$type), position = "genome",
ratio = ((.x$ratio[2]*.x$number[2]) + (.x$ratio[1]+.x$number[1])) /
(.x$number[1]+.x$number[2]), number = .x$number[1] + .x$number[2],
percentage = .x$percentage[1] + .x$percentage[2]))
# A tibble: 6 x 5
type position ratio number percentage
<chr> <chr> <dbl> <int> <dbl>
1 DNA intergenic 0.000269 225173 40.8
2 DNA intragenic 0.000218 41250 7.47
3 DNA genome 0.845 266423 48.2
4 LINE intergenic 0.000276 48619 8.80
5 LINE intragenic 0.000310 9578 1.73
6 LINE genome 0.835 58197 10.5
这是一个解决方案。
dplyr
并不意味着创建新行,因为结果通常不被认为是“整洁的”。在您的情况下,您想汇总数据(为此我使用了自定义函数)。您可以单独使用摘要,也可以使用 bind_rows()
将其添加到原始 table.
注意,您可能需要检查 number_intragenic
及其朋友的长度是否为 1,这可能会防止一些意外错误,例如 stopifnot(length(number_intragenic)==1
.
library(tidyverse)
df = read.table(header=T, text="
type position ratio number percentage
DNA intergenic 0.00026933362 225173 40.757876065
DNA intragenic 0.00021799943 41250 7.466536342
LINE intergenic 0.00027633335 48619 8.800376494
LINE intragenic 0.00031015097 9578 1.733684487
")
get_ratio = function(number, ratio, position){
number_intragenic = number[position=="intragenic"]
ratio_intragenic = ratio[position=="intragenic"]
number_intergenic = number[position=="intergenic"]
ratio_intergenic = ratio[position=="intergenic"]
((number_intragenic * ratio_intragenic) + (number_intergenic + ratio_intergenic))/(number_intragenic+number_intergenic)
}
df_summary = df %>%
group_by(type) %>%
summarise(ratio=get_ratio(number, ratio, position),
number=sum(number),
percentage=sum(percentage)) %>%
mutate(position="genome", .after="type")
bind_rows(df, df_summary) %>%
arrange(type)
#> type position ratio number percentage
#> 1 DNA intergenic 0.0002693336 225173 40.757876
#> 2 DNA intragenic 0.0002179994 41250 7.466536
#> 3 DNA genome 0.8452047787 266423 48.224412
#> 4 LINE intergenic 0.0002763333 48619 8.800376
#> 5 LINE intragenic 0.0003101510 9578 1.733684
#> 6 LINE genome 0.8354721189 58197 10.534061
由 reprex package (v2.0.0)
于 2021-05-12 创建
我有以下table,我想修改:
type | position | ratio | number | percentage |
---|---|---|---|---|
DNA | intergenic | 0.00026933362 | 225173 | 40.757876065 |
DNA | intragenic | 0.00021799943 | 41250 | 7.466536342 |
LINE | intergenic | 0.00027633335 | 48619 | 8.800376494 |
LINE | intragenic | 0.00031015097 | 9578 | 1.733684487 |
我想添加包含以下修改的行:
类型:如果值“类型”在两行之间相同(在我的情况下总是如此),请将其再次添加到列“类型”的单独行中。
位置:将值从 intergenic/intragenic 更改为 "genome" if (1)
比率:比率值将是根据相同类型值的基因间行和基因内行的比率计算的加权平均值:
((number_intragenic * ratio_intragenic) + (number_intergenic * ratio_intergenic))/(number_intragenic + number_intergenic)number:相同类型的数字值之和:sum(number_intergenic + number_intragenic)
相同类型的百分比值之和:sum(percentage_intergenic + percentage_intragenic)
我的问题是我不知道如何通过对现有行进行特定计算来向数据框添加行。在 dplyr 中使用 mutate 添加列很容易。我如何为行执行此操作?
如果解决方案在 dplyr 中提供,我会更喜欢。
编辑:加权平均值的公式是错误的。我在公式的以下部分添加了一个 + 号而不是 * 号:(number_intergenic + ratio_intergenic)。现在已经修复了。
献给亲爱的@akrun ,是他教会了我如何做到这一点:
library(dplyr)
library(purrr)
library(tibble)
df %>%
group_split(type) %>%
map_dfr(~ add_row(.x, type = first(.x$type), position = "genome",
ratio = ((.x$ratio[2]*.x$number[2]) + (.x$ratio[1]+.x$number[1])) /
(.x$number[1]+.x$number[2]), number = .x$number[1] + .x$number[2],
percentage = .x$percentage[1] + .x$percentage[2]))
# A tibble: 6 x 5
type position ratio number percentage
<chr> <chr> <dbl> <int> <dbl>
1 DNA intergenic 0.000269 225173 40.8
2 DNA intragenic 0.000218 41250 7.47
3 DNA genome 0.845 266423 48.2
4 LINE intergenic 0.000276 48619 8.80
5 LINE intragenic 0.000310 9578 1.73
6 LINE genome 0.835 58197 10.5
这是一个解决方案。
dplyr
并不意味着创建新行,因为结果通常不被认为是“整洁的”。在您的情况下,您想汇总数据(为此我使用了自定义函数)。您可以单独使用摘要,也可以使用 bind_rows()
将其添加到原始 table.
注意,您可能需要检查 number_intragenic
及其朋友的长度是否为 1,这可能会防止一些意外错误,例如 stopifnot(length(number_intragenic)==1
.
library(tidyverse)
df = read.table(header=T, text="
type position ratio number percentage
DNA intergenic 0.00026933362 225173 40.757876065
DNA intragenic 0.00021799943 41250 7.466536342
LINE intergenic 0.00027633335 48619 8.800376494
LINE intragenic 0.00031015097 9578 1.733684487
")
get_ratio = function(number, ratio, position){
number_intragenic = number[position=="intragenic"]
ratio_intragenic = ratio[position=="intragenic"]
number_intergenic = number[position=="intergenic"]
ratio_intergenic = ratio[position=="intergenic"]
((number_intragenic * ratio_intragenic) + (number_intergenic + ratio_intergenic))/(number_intragenic+number_intergenic)
}
df_summary = df %>%
group_by(type) %>%
summarise(ratio=get_ratio(number, ratio, position),
number=sum(number),
percentage=sum(percentage)) %>%
mutate(position="genome", .after="type")
bind_rows(df, df_summary) %>%
arrange(type)
#> type position ratio number percentage
#> 1 DNA intergenic 0.0002693336 225173 40.757876
#> 2 DNA intragenic 0.0002179994 41250 7.466536
#> 3 DNA genome 0.8452047787 266423 48.224412
#> 4 LINE intergenic 0.0002763333 48619 8.800376
#> 5 LINE intragenic 0.0003101510 9578 1.733684
#> 6 LINE genome 0.8354721189 58197 10.534061
由 reprex package (v2.0.0)
于 2021-05-12 创建