在 Dataframe 的多个列中使用基于“or”条件的dplyr summary和group_by函数

ar5n3qh5  于 2023-03-15  发布在  其他
关注(0)|答案(3)|浏览(172)

我可以在下面的df中测量x列中1示例的比例:

df <- tribble(
  ~id, ~x, 
  'A',0,
  'A',1,
  'A',1,
  'B',0,
  'B',0,
  'B',1,
  'C',1,
  'C',0,
  'C',0,
  'C',1,
)

df %>%
  group_by(id) %>%
  summarise(
    result = round(prop.table(table(x))["1"]*100, digits = 2)
    )

# A tibble: 3 x 2
  id    result
  <chr>  <dbl>
1 A       66.7
2 B       33.3
3 C       50

但我真正想要的是,如果x、y和z列中的任何一列的值为1,则测量1示例的比例。例如,在下面的A类情况中,第一行的值为零,因为所有x、y和z值均为零,但第二行和第三行的值为1,因为x、y和z列中至少有一列出现了1。因此,同样,类别A在使用上述group_bysummarize函数的情况下具有66.7%的1值(类别A的三行中有两行的值为1)

df <- tribble(
  ~id, ~x, ~y, ~z
  'A',0,0,0,
  'A',1,0,0,
  'A',1,1,0,
  'B',0,0,0,
  'B',0,0,0,
  'B',1,0,0,
  'C',1,0,0,
  'C',0,0,0,
  'C',0,0,0,
  'C',1,0,0,
)
9w11ddsr

9w11ddsr1#

使用mean + rowSums

df %>%
  group_by(id) %>%
  summarise(
    result = mean(rowSums(across(x:z)) >= 1)
  )

# A tibble: 3 × 2
  id    result
  <chr>  <dbl>
1 A      0.667
2 B      0.333
3 C      0.5
cgfeq70w

cgfeq70w2#

我们可以使用

library(dplyr) # version >= 1.1.0
df %>% 
   reframe(result = mean(if_any(x:z)), .by = id)
  • 输出
# A tibble: 3 × 2
  id    result
  <chr>  <dbl>
1 A      0.667
2 B      0.333
3 C      0.5

根据?reframe
reframe()通过将函数应用于现有 Dataframe 的列来创建新的 Dataframe 。它与summarise()非常相似,但有两个很大的区别:
reframe()可以为每个组返回任意数量的行,而summarise()可以将每个组缩减为一行。
reframe()总是返回一个未分组的 Dataframe ,而summarise()可能返回一个分组的或按行的 Dataframe ,这取决于场景。
我们希望summarise()比reframe()使用得更频繁,但是当你需要应用一个不返回一个汇总值的复杂函数时,reframe()会特别有用。

k97glaaz

k97glaaz3#

可以在变量中使用OR并计算其平均值或测试sum >= 1
我同意托马斯和Maël mean的观点,这是一种更优雅的方式

df %>%
  group_by(id) %>%
  summarise(result = round(mean(x|y|z), digits = 2))

相关问题