我正试图创建一个函数来处理不同的数据集,但在执行此任务时遇到了一些问题。我在下面的dput((输出中提供了我试图操作的数据的简化版本:
structure(list(id = structure(c(2, 4, 6, 8, 10), label = "iid", format.spss = "F4.0", display_width = 0L), A = c(13, 9, 14, 14, 13), B = c(12, 0, 9, 3, 10), C = c(13, 8, 14, 13, 11)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))
我正在尝试做几件事,但由于数据的格式化方式,我在不同的时刻遇到了困难。首先,我需要将每行的列A:D中的值相加为一个名为total
的变量。接下来,我需要通过将每个列A:D除以total
来计算概率。
这是我面临的一些问题。我写了一个函数来执行上述操作:
functa <- function(x, id, vars) {
x %>%
mutate(total = rowSums(.[vars])) %>%
mutate(prob = .[vars]/total)
}
当我使用以下行调用函数时:
test <- functa(df_ED, "pid", c("A", "B", "C", "D"))
我得到一个有5个观测值的物体,但只有7个变量(而不是10个(。当我检查对象时,我会看到4个新变量(即prob.A、prob.B、prob.C、prob.D(,但它们是作为单个变量读取的。
因此,我想在此数据集上执行的任何后续操作都无法按预期进行。在过去的两天里,我一直在研究这一问题,但找不到任何关于这一现象的信息,我猜我有点不知所措。
我这个功能的最终目标是:
- 计算
total
变量(a:D之和( - 计算一个
prob
变量,该变量应输出4个变量(即a/total、B/total等( - 重新编码
prob
变量,使得所有无穷大的值(即"Inf"(被重新编码为0 - 将所有4个
prob
变量相加为一个totalprob
变量
如有任何见解,不胜感激!
当您想将函数应用于多列时,请使用across
:
library(dplyr)
functa <- function(x, id, vars) {
x %>%
#sum all vars column
mutate(total = rowSums(.[vars]),
#Divide vars column with total and create new columns with prob
across(all_of(vars), ~./total, .names = '{col}_prob'),
#Replace infinite value in prob column with 0
across(ends_with('_prob'), ~replace(., is.infinite(.), 0))) %>%
#Sum all prob columns.
mutate(totalprob = rowSums(select(., ends_with('prob'))))
}
functa(df_ED, "pid", c("A", "B", "C"))
# id A B C total A_prob B_prob C_prob totalprob
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 2 13 12 13 38 0.342 0.316 0.342 1
#2 4 9 0 8 17 0.529 0 0.471 1
#3 6 14 9 14 37 0.378 0.243 0.378 1
#4 8 14 3 13 30 0.467 0.1 0.433 1
#5 10 13 10 11 34 0.382 0.294 0.324 1
另一种解决方案是更改表的布局,在第一步中使用pivot_longer
计算概率,在下一步使用pivot_wider
获得所需的最终布局。
> df %>%
+ pivot_longer(-id, names_to = "key", values_to = "value") %>%
+ group_by(id) %>%
+ mutate(prob = value / sum(value)) %>%
+ pivot_wider(names_from = key, values_from = c(value, prob))
# A tibble: 5 x 7
# Groups: id [5]
id value_A value_B value_C prob_A prob_B prob_C
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2 13 12 13 0.342 0.316 0.342
2 4 9 0 8 0.529 0 0.471
3 6 14 9 14 0.378 0.243 0.378
4 8 14 3 13 0.467 0.1 0.433
5 10 13 10 11 0.382 0.294 0.324