如何计算满足R中特定条件的每列(按组)中的行数

时间:2020-10-30 15:57:56

标签: r

我有一个与这里的链接(How to Count number of rows in every column that meets a specific criteria in R)类似的问题,但是我似乎无法使用相同的解决方案,因此我再次伸出援手。

我有一个数据集

mydata <- read.table(header=TRUE, text="
  rime   point   sound   school
  50      80       50     es
  80      80       20     es
  5       90       80     es
  0       10       80     ms
  50      80       50     ms
  80      80       20     ms
  5       90       80     hs
  0       10       80     hs
  5       90       80     hs
  0       10       80     hs
")

对于每列,我想知道学校观察到的百分比> = 50%。最终产品应该是一个看起来像这样的数据框。

mydata_clean <- read.table(header=TRUE, text="
  rime      point     sound     school
  66.7%     100%      66.7%     es
  66.7%     66.7%     66.7%     ms
  0%        50%       100%      hs
")

这似乎是group_by(School)的明确案例,然后进行总结,但是我没有得到我需要的信息。

我尝试了以下代码:

mydata %>%
  group_by(school) %>%
  summarise_at(vars(rime, point, sound), sum)

但这只会给我每组每一列的总和,这不是我想要的。

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

尝试这种tidyverse方法。您可以使用pivot_longer()保持学校可变性,从而将数据重塑为长时间。之后,创建一个变量以检查值是否达到所需条件。最后,summarise()允许计算期望值,这些期望值可以使用paste0()格式化为百分比。提醒一下,列是字符类型。这里的代码:

library(tidyverse)
#Code
mydata %>% pivot_longer(-school) %>%
  group_by(school,name) %>%
  mutate(Var=ifelse(value>=50,1,0)) %>%
  summarise(Perc=paste0(100*round(mean(Var),3),'%')) %>%
  pivot_wider(names_from = name,values_from=Perc)

输出:

# A tibble: 3 x 4
# Groups:   school [3]
  school point rime  sound
  <fct>  <chr> <chr> <chr>
1 es     100%  66.7% 66.7%
2 hs     50%   0%    100% 
3 ms     66.7% 66.7% 66.7%

答案 1 :(得分:1)

这是一种方法。
它首先根据要大于或等于50的列将要汇总的列转换为逻辑值。然后按学校分组并计算百分比。

library(dplyr)

mydata %>%
  mutate(across(rime:sound, `>=`, 50)) %>%
  group_by(school) %>%
  summarise(across(rime:sound, mean), .groups = "keep") %>%
  mutate(across(rime:sound, scales::percent))
## A tibble: 3 x 4
## Groups:   school [3]
#  school rime  point sound
#  <chr>  <chr> <chr> <chr>
#1 es     67%   100%  67%  
#2 hs     0%    50%   100% 
#3 ms     67%   67%   67%  

答案 2 :(得分:1)

我们可以在没有任何ifelse的情况下从逻辑转换为二进制

library(dplyr)
library(tidyr)
library(stringr)
mydata %>% 
    pivot_longer(cols = - school) %>%
    group_by(school, name) %>%
    mutate(Var = +(value >= 50)) %>% 
    summarise(Perc = str_c(100 * round(mean(Var), 3), '%')) %>% 
    pivot_wider(names_from = name, values_from = Perc)

-输出

# A tibble: 3 x 4
# Groups:   school [3]
#  school point rime  sound
#  <chr>  <chr> <chr> <chr>
#1 es     100%  66.7% 66.7%
#2 hs     50%   0%    100% 
#3 ms     66.7% 66.7% 66.7%