下面是我试图实现的一个示例:
df <- data.frame(label = c(rep("ABC", 5), rep("CDE", 5), rep("FGH", 5)), x = runif(15, 0, 100))
df %>% group_by(label) %>%
summarise(across(everything(), list(lessthan_10 = ~sum(. < 10), lessthan_20 = ~sum(. < 20), lessthan_30 = ~sum(. < 20), lessthan_40 = ~sum(. < 40))))
在这种情况下,我将在摘要中计算4个不同的列(对小于10、小于20、小于30和小于40的条目进行计数(。实际上,我想使用一个接受x和100个不同参数的自定义函数来计算100个不同的列。有没有一种方法可以使用循环或列表来实现这一点,而不必写出我想要计算的每一列?
您可以使用purrr::map_dfc
:
library(tidyverse)
df %>%
group_by(label) %>%
summarise(map_dfc(seq(10, 40, 10), ~ tibble("x_lessthan_{.x}" := sum(x < .x))))
label x_lessthan_10 x_lessthan_20 x_lessthan_30 x_lessthan_40
<chr> <int> <int> <int> <int>
1 ABC 0 3 3 3
2 CDE 0 2 3 4
3 FGH 1 2 3 3
1(dplyr/tidyr使用末尾注释中的输入,为每个标签创建4行,每行包含一个包含x值和10、20、30、40之一的列表。然后为每一行创建相应的总和和总和名称,并最终将其转换为宽格式
将paste0
更改为您想要的任何格式,例如sprintf("Less_than_%d", s)
将强制其不使用e表示法。
library(dplyr)
library(tidyr)
df %>%
group_by(label) %>%
summarize(x = list(x), s = seq(10, 40, 10)) %>%
rowwise %>%
mutate(value = sum(x < s), name = paste0("Less_than_", s)) %>%
pivot_wider(label)
给予:
# A tibble: 3 × 5
label Less_than_10 Less_than_20 Less_than_30 Less_than_40
<chr> <int> <int> <int> <int>
1 ABC 0 0 1 1
2 CDE 1 1 1 1
3 FGH 0 1 1 1
2(Base R要获得仅限碱基的解决方案,请在如图所示定义的s
和label
上使用outer
。
s <- seq(10, 40, 10)
names(s) <- paste("Less_than_", s)
label <- unique(df$label)
f <- function(g, s) sum(subset(df, label == g)$x < s)
data.frame(label, outer(label, s, Vectorize(f)))
备注
为了使df
的定义可重复,我们添加了一个set.seed
。
set.seed(123)
df <- data.frame(label = c(rep("ABC", 5), rep("CDE", 5), rep("FGH", 5)),
x = runif(15, 0, 100))
给予:
> df
label x
1 ABC 28.75775
2 ABC 78.83051
3 ABC 40.89769
4 ABC 88.30174
5 ABC 94.04673
6 CDE 4.55565
7 CDE 52.81055
8 CDE 89.24190
9 CDE 55.14350
10 CDE 45.66147
11 FGH 95.68333
12 FGH 45.33342
13 FGH 67.75706
14 FGH 57.26334
15 FGH 10.29247