如何通过将第一行除以第三行来创建行

时间:2019-07-12 13:40:11

标签: r dplyr tidyverse

我有一个数据集,该数据集的值在第一行,总计在第三行。我想创建第四行,它是第一行占总数的百分比,这可以通过将第一行除以第四行来完成。

下面是数据框的结构

ds = structure(list(t1 = structure(c("1", "2", "Total"), label = "currently smoke any tobacco product", labels = c(no = 0, 
yes = 1), class = "haven_labelled"), c1Female = c(679357.516868591, 
8394232.81394577, 9073590.33081436), c1Male = c(2254232.8617363, 
5802560.20343018, 8056793.06516647), se.c1Female = c(63743.4459540534, 
421866.610586848, 485610.056540901), se.c1Male = c(185544.754820322, 
386138.725133411, 571683.479953732), Total_1 = c(`1` = 2933590.37860489, 
`2` = 14196793.0173759, `3` = 17130383.3959808), per = c(`1` = 0.171250713471665, 
`2` = 0.828749286528335, `3` = 1)), class = "data.frame", row.names = c(NA, 
-3L))

我的尝试以及这有什么问题

ds %>% mutate(percentage = .[1,]/.[3,])

应该是输出:以下是我想要的输出数据帧的输出

structure(list(t1 = structure(c(1L, 2L, 4L, 3L), .Label = c("1", 
"2", "Percentage", "Total"), class = "factor"), c1Female = c(679357.517, 
8394232.814, 9073590.331, 0.074871963), c1Male = c(2254232.86, 
5802560.2, 8056793.07, 0.279792821), se.c1Female = c(63743.446, 
421866.611, 485610.057, 0.131264674), se.c1Male = c(185544.755, 
386138.725, 571683.48, 0.324558539), Total_1 = c(2933590.38, 
14196793.02, 17130383.4, 0.171250714), per = c(0.171250713, 0.828749287, 
1, 0.171250713)), class = "data.frame", row.names = c(NA, -4L
))

分享共享方法。另外,请务必在行代码下方告诉这种方法有什么问题

ds %>% mutate(percentage = .[1,]/.[3,])

1 个答案:

答案 0 :(得分:2)

我们可以使用summarise_at划分多个列值以返回单行,然后与原始数据集绑定

library(dplyr)
ds %>% 
    summarise_at(-1, ~ .[1]/.[3]) %>%
    mutate(t1 = 'Percentage') %>%
    bind_rows(ds, .)
#       t1     c1Female       c1Male  se.c1Female    se.c1Male      Total_1       per
#1          1 6.793575e+05 2.254233e+06 6.374345e+04 1.855448e+05 2.933590e+06 0.1712507
#2          2 8.394233e+06 5.802560e+06 4.218666e+05 3.861387e+05 1.419679e+07 0.8287493
#3      Total 9.073590e+06 8.056793e+06 4.856101e+05 5.716835e+05 1.713038e+07 1.0000000
#4 Percentage 7.487196e-02 2.797928e-01 1.312647e-01 3.245585e-01 1.712507e-01 0.1712507

或者另一个选择是add_row

ds %>%
   add_row(t1 = 'Percentage') %>% 
   mutate_at(-1, ~ replace_na(., .[1]/.[3]))

或者在add_row步骤本身中完成

ds %>% 
   add_row(t1 = 'Percentage', !!!as.list(.[-1][1,]/.[-1][3,]))
 #      t1     c1Female       c1Male  se.c1Female    se.c1Male      Total_1       per
#1          1 6.793575e+05 2.254233e+06 6.374345e+04 1.855448e+05 2.933590e+06 0.1712507
#2          2 8.394233e+06 5.802560e+06 4.218666e+05 3.861387e+05 1.419679e+07 0.8287493
#3      Total 9.073590e+06 8.056793e+06 4.856101e+05 5.716835e+05 1.713038e+07 1.0000000
#4 Percentage 7.487196e-02 2.797928e-01 1.312647e-01 3.245585e-01 1.712507e-01 0.1712507