首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >函数从数据中提取最高的n个分数,并使用‘`apply`’或dplyr ` `rowwise`‘找到它们的平均值。

函数从数据中提取最高的n个分数,并使用‘`apply`’或dplyr ` `rowwise`‘找到它们的平均值。
EN

Stack Overflow用户
提问于 2022-01-16 18:47:56
回答 5查看 305关注 0票数 9

数据文件看起来像这样

代码语言:javascript
运行
复制
df = data.frame(name = c("A","B","C"),
               exam1 = c(2,6,4),
               exam2 = c(3,5,6),
               exam3 = c(5,3,3),
               exam4 = c(1,NA,5))

我希望提取每个“名称”的前3名,并使用apply()或dplyr 行式()函数找到它们的平均值。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2022-01-16 18:49:56

使用apply,使用MARGIN = 1循环数字列上的行,sort,根据decreasing = TRUE/FALSE获取head/tail,并在base R中返回mean

代码语言:javascript
运行
复制
apply(df[-1], 1, FUN = function(x) mean(head(sort(x, decreasing = TRUE), 3)))
[1] 3.333333 4.666667 5.000000

或使用dplyr/rowwise

代码语言:javascript
运行
复制
library(dplyr)
df %>%
  rowwise %>%
  mutate(Mean = mean(head(sort(c_across(where(is.numeric)), 
       decreasing = TRUE), 3))) %>% 
  ungroup
# A tibble: 3 × 6
  name  exam1 exam2 exam3 exam4  Mean
  <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A         2     3     5     1  3.33
2 B         6     5     3    NA  4.67
3 C         4     6     3     5  5   
票数 7
EN

Stack Overflow用户

发布于 2022-01-16 18:58:33

下面是一种使用top_n进行旋转和使用的替代方法:这将只返回前3位:

代码语言:javascript
运行
复制
library(dplyr)
library(tidyr)
df %>% 
  pivot_longer(
    -name,
    names_to = "exam",
    values_to = "value"
  ) %>% 
  group_by(name) %>% 
  top_n(3, value) %>% 
  mutate(mean = mean(value)) %>% 
  pivot_wider(
    names_from = exam, 
    values_from = value
  )
代码语言:javascript
运行
复制
  name   mean exam1 exam2 exam3 exam4
  <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A      3.33     2     3     5    NA
2 B      4.67     6     5     3    NA
3 C      5        4     6    NA     5

或:

代码语言:javascript
运行
复制
library(tidyr)
df %>% 
  pivot_longer(
    -name,
    names_to = "exam",
    values_to = "value"
  ) %>% 
  group_by(name) %>% 
  top_n(3, value) %>% 
  summarise(mean = mean(value))
代码语言:javascript
运行
复制
 name   mean
  <chr> <dbl>
1 A      3.33
2 B      4.67
3 C      5   
票数 4
EN

Stack Overflow用户

发布于 2022-01-16 19:00:25

使用purrr::pmap_dfr

代码语言:javascript
运行
复制
library(tidyverse)

df = data.frame(name = c("A","B","C"),
                exam1 = c(2,6,4),
                exam2 = c(3,5,6),
                exam3 = c(5,3,3),
                exam4 = c(1,NA,5))

df %>% 
  pmap_dfr(~ list(means = mean(sort(c(..2,..3,..4,..5), decreasing=T)[1:3]))) %>%
  bind_cols(df,.)

#>   name exam1 exam2 exam3 exam4    means
#> 1    A     2     3     5     1 3.333333
#> 2    B     6     5     3    NA 4.666667
#> 3    C     4     6     3     5 5.000000

另一种可能的解决方案,基于tidyr::pivot_longer而不使用rowwise

代码语言:javascript
运行
复制
library(tidyverse)

df = data.frame(name = c("A","B","C"),
                exam1 = c(2,6,4),
                exam2 = c(3,5,6),
                exam3 = c(5,3,3),
                exam4 = c(1,NA,5))

df %>% 
  pivot_longer(cols = 2:5, names_to = "names") %>% 
  group_by(name) %>% 
  slice_max(value, n=3) %>% 
  summarise(mean = mean(value)) %>% 
  inner_join(df)

#> Joining, by = "name"
#> # A tibble: 3 × 6
#>   name   mean exam1 exam2 exam3 exam4
#>   <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 A      3.33     2     3     5     1
#> 2 B      4.67     6     5     3    NA
#> 3 C      5        4     6     3     5
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70733133

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档