需要帮助创建一个循环,在 group_by() 之后将列名输入 transmute()

Need help creating a loop where you feed column names into transmute() after group_by()

我目前有一个数据框df,其中第一列是自我识别的种族(因素),其余列都是具有二进制值的症状(数字)(0 = 不存在,1 = 存在) .每行代表一名患者(在此步骤之前,其他人口统计信息已从数据框中清除)。随机示例:

种族(因素) 头痛 (num) 感觉异常(数量) 胃灼热(数量)
白色 0 0 1
亚洲人 0 1 0
白色 1 1 0
亚洲人 1 1 1
黑色 0 1 0
亚洲人 0 0 1
黑色 1 0 1
白色 1 0 1

我的目标是创建一个数据框,其中第一列是 3 个独特的种族因素,每个症状列都有该种族中有症状的人的百分比。比如这样:

种族(因素) 头痛 感觉异常 胃灼热
白色 0.666 0.333 0.666
亚洲人 0.333 0.666 0.666
黑色 0.5 0.5 0.5

此代码非常适合为一列创建数据框

unique(df %>% group_by(race) %>% drop_na %>% transmute(Headache = sum(Headache)/length(race)) %>% ungroup)

我最终会得到一个数据框,例如

种族(因素) 头痛
白色 0.6666
亚洲人 0.3333
黑色 0.5

我可以手动重复这个过程并合并结果数据框,但我的实际数据框有 60 多个症状,所以这会非常乏味和丑陋。

我想我可以为此创建一个循环。

这一步是我遇到困难的地方。

我试过了

y <- tibble
for (i in colnames(df)[-1]) {
    z <- unique(df %>% group_by(race) %>% 
drop_na %>% transmute(i = sum(i)/length(race)) %>% ungroup)
    y <- merge(y, z)
}

并得到

Error: Problem with `mutate()` column `i`.
ℹ `i = sum(i)/length(race)`.
x invalid 'type' (character) of argument
ℹ The error occurred in group 1: race = Asian.
Run `rlang::last_error()` to see where the error occurred.

然后我尝试了

y <- tibble
for (i in 2:4) {
    z <- unique(df %>% group_by(race) %>% 
drop_na %>% mutate_at(colnames(bp1[i])) = sum(colnames(bp1[i]))/length(race)) %>% ungroup)
    y <- merge(y, z)
}

产生

Error: unexpected '=' in:
"        z <- unique(df %>% group_by(race) %>% 
drop_na %>% mutate_at(get(colnames(df[i])) ="
>   y <- merge(y, z)
Error in as.data.frame.default(x) : 
  cannot coerce class ‘"function"’ to a data.frame
> }
Error: unexpected '}' in "}"

我认为发生这些错误的原因是,当我调用列名时,它生成的是一个字符,而不是转换函数要处理的对象(或类似的东西?我很新到 R 所以不确定正确的术语)。我假设这将适用于所有 dplyr 包。

有办法解决这个问题吗?如果有建议,我很乐意后退几步,例如,如果我的原始数据框应该更改以使这一步更容易。

P.S。作为旁注,如果有人对如何在名为“总计”的种族下创建第四行以及随后在症状列中的跨率总患病率提出建议,这也很有用!

例如:

种族(因素) 头痛 感觉异常 胃灼热
白色 0.666 0.333 0.666
亚洲人 0.333 0.666 0.666
黑色 0.5 0.5 0.5
总计 0.5 0.5 0.625

如果数据中有二进制值,一种简化方法是对每个唯一值取平均值 Race

library(dplyr)
df %>% group_by(Race) %>% summarise(across(.fns = mean, na.rm = TRUE))

#  Race  Headache Paraesthesias Heartburn
#  <chr>    <dbl>         <dbl>     <dbl>
#1 Asian    0.333         0.667     0.667
#2 Black    0.5           0.5       0.5  
#3 White    0.667         0.333     0.667

在基础 R 中,您可以使用 -

aggregate(.~Race, df, mean, na.rm = TRUE)

数据

如果以可重现的格式共享数据,会更容易提供帮助。

df <- structure(list(Race = c("White", "Asian", "White", "Asian", "Black", 
"Asian", "Black", "White"), Headache = c(0L, 0L, 1L, 1L, 0L, 
0L, 1L, 1L), Paraesthesias = c(0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L
), Heartburn = c(1L, 0L, 0L, 1L, 0L, 1L, 1L, 1L)), row.names = c(NA, 
-8L), class = "data.frame")

我们可以使用

library(data.table)
setDT(df)[, lapply(.SD, mean, na.rm = TRUE), by = Race]

数据

df <- structure(list(Race = c("White", "Asian", "White", "Asian", "Black", 
"Asian", "Black", "White"), Headache = c(0L, 0L, 1L, 1L, 0L, 
0L, 1L, 1L), Paraesthesias = c(0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L
), Heartburn = c(1L, 0L, 0L, 1L, 0L, 1L, 1L, 1L)), row.names = c(NA, 
-8L), class = "data.frame")