如果我有一个数据框:
d = data.frame(sample=c("a2","a3"),a=c(1,5),b=c(4,5),c=c(6,4))
d
sample a b c
1 a2 1 4 6
2 a3 5 5 4
Run Code Online (Sandbox Code Playgroud)
我如何使用 dplyr 将每列的总和除以整个数据帧的总和,所以我最终得到一个如下所示的数据帧:
a b c
1 6/25 9/25 10/25
Run Code Online (Sandbox Code Playgroud)
我试着做
d <- d %>%
mutate_if(is.numeric, funs(colSums(d)/sum(d)))
Run Code Online (Sandbox Code Playgroud)
但不断返回错误。
提前致谢!
除了 2a 和 2b,在这些替代方案中的每一个中,如果可以假设我们知道只有第一列是非数字的,我们可以用 d[-1] 替换管道的前两个组件。
1) Base R使用 base R,我们得到了一个直接的解决方案:
d |> Filter(f = is.numeric) |> colSums() |> prop.table()
## a b c
## 0.24 0.36 0.40
Run Code Online (Sandbox Code Playgroud)
2) dplyr与 dplyr:
library(dplyr)
d %>%
select(where(is.numeric)) %>%
summarize(across(.fn = sum) / sum(.))
## a b c
## 1 0.24 0.36 0.4
Run Code Online (Sandbox Code Playgroud)
2a)或
d %>%
summarize(across(where(is.numeric), sum)) %>%
{ . / sum(.) }
Run Code Online (Sandbox Code Playgroud)
2b)诸如 *_if 函数之类的作用域函数如今已被 cross 取代,但它们仍然可用,因此如果您无论如何都想使用它们,请尝试使用与问题中的代码相近的方法:
d %>%
summarize_if(is.numeric, sum) %>%
{ . / sum(.) }
Run Code Online (Sandbox Code Playgroud)
3)collapse 用collapse 包,得到数值变量(nv),对每一列求和(fsum),然后取比例。当我在此数据上对其进行基准测试时,它的运行速度比 (1) 快 3 倍,比 (2) 快 100 倍以上,比 (4) 快 300 倍。
library(collapse)
d |> nv() |> fsum() |> fsum(TRA = "/")
## a b c
## 0.24 0.36 0.40
Run Code Online (Sandbox Code Playgroud)
4) dplyr/tidyr使用 tidyr 和 dplyr 我们可以转换为长格式,处理并转换回来。
library(dplyr)
library(tidyr)
d %>%
select(where(is.numeric)) %>%
pivot_longer(everything()) %>%
group_by(name) %>%
summarize(value = sum(value) / sum(.$value), .groups = "drop") %>%
pivot_wider
## # A tibble: 1 x 3
## a b c
## <dbl> <dbl> <dbl>
## 1 0.24 0.36 0.4
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
110 次 |
| 最近记录: |