繁体   English   中英

使用 R dplyr package 根据其他列值操作列

[英]Manipulating a column based on other column values with R dplyr package

我想为每个学生选择最好的 2 个测验考试结果(最高分和最高出勤率),并消除 3 个测验考试中最弱的测验。 我们可能会说,我想从每行的 3 列中选择最好的 2 列。 然后创建一个包含StudentID, ExamQuiz1, ExamQuiz2, ExamMidterm and ExamFinal的新数据框。 我可以通过循环遍历表格来处理它,这在 R 中效率太低我假设。 处理 dplyr package 问题的有效方法是什么?

极简数据

伪数据框放置在底部。 G ”表示学生没有参加考试,所以我想保留该值而不是将其替换为 0。例如,如果他使用 G ( ExamQuiz1 )、0 ( ExamQuiz2 )、10 ( ExamQuiz3 ) 得到这个场景,我必须选择 0 作为ExamQuiz1和 10 作为ExamQuiz2用于测验输入。 因为出勤方面0比G好。 如果有结果(带数字),则表示学生已经参加。 ExamQuiz1, ExamQuiz2, ExamMidterm and ExamFinal列下的每个单元格都可能具有数字(考试结果)或字符值(“ G ”> 未参加)。 我不会触及 ExamMidterm 和 ExamFinal 列的任何值。 主要思想仅与ExamQuiz1, ExamQuiz2, and ExamQuiz3的列相关。

   StudentID  ExamQuiz1  ExamQuiz2  ExamQuiz3  ExamMidterm  ExamFinal
1      11111          0          G          G            G          G
2      22222          0          G         43           71         18
3      33333          0          G          G            G          G
4      44444          0          G          G            G          G
5      55555         60         38          G           64         27
6      66666          0          G          G            G          G

编辑:仍然有一些评论者不断指出数据不整洁。 正如我在评论中解释的那样,这样做的原因或您提供的整理方法对我来说没有意义。 出于这个原因,我在问题主体上放置了更多的解释,而不改变数据的结构。

一基R解决方案

cbind(df[-(2:4)], t(apply(df[2:4], 1, function(x){
  c(x[x == "G"], sort(x[x != "G"]))[-1]
})))

#   StudentID Midterm Final  1  2
# 1     11111       G     G  G  0
# 2     22222      71    18  0 43
# 3     33333       G     G  G  0
# 4     44444       G     G  G  0
# 5     55555      64    27 38 60
# 6     66666       G     G  G  0

在您的规则中,应将G放在任何数字前面。 所以起初我把所有现有的G放在一个向量的开头,然后 append 排序分数。 删除向量中的第一个元素后,将保留前 2 个分数。

这是dplyr across新方法(版本1.0.0或更高版本):

假设没有人可以得到负分并且缺席比得到零更糟糕,我们可以将G设置为-1

library(dplyr)
data %>% 
  mutate(across(-StudentID, ~case_when(. == "G" ~ -1,
                                       TRUE ~ as.numeric(.)))) %>%
  rowwise() %>%
  mutate(TopQuiz = max(c_across(starts_with("Quiz"))),
         SecondQuiz = sort(c_across(starts_with("Quiz")),
                           decreasing = TRUE)[2]) %>%
  dplyr::select(StudentID, TopQuiz, SecondQuiz, Midterm, Final) %>%
  mutate(across(-StudentID, ~case_when(. == -1 ~ "G",
                                       TRUE ~ as.character(.))))
##A tibble: 6 x 5
## Rowwise: 
#  StudentID TopQuiz SecondQuiz Midterm Final
#      <int> <chr>   <chr>      <chr>   <chr>
#1     11111 0       G          G       G    
#2     22222 43      0          71      18   
#3     33333 0       G          G       G    
#4     44444 0       G          G       G    
#5     55555 60      38         64      27   
#6     66666 0       G          G       G     

应用dplyrstringr的方式略有不同,方法是让 G NA 进行数学运算,然后将 NA 放回 G 并返回字符。

library(dplyr)
library(stringr)


newgrades <- grades %>% 
  mutate(across(starts_with("Quiz"), ~ str_replace(., "G", NA_character_))) %>%
  mutate(across(starts_with("Quiz"), as.numeric)) %>%
  rowwise() %>%
  mutate(TopQuiz = max(c_across(starts_with("Quiz")), na.rm = TRUE),
         NextBestQuiz = sort(c_across(starts_with("Quiz")),
                             decreasing = TRUE)[2]) %>%
  mutate(across(ends_with("Quiz"), as.character)) %>%
  mutate(across(ends_with("Quiz"), ~ str_replace_na(., replacement = "G"))) %>%
  select(id, TopQuiz, NextBestQuiz, Midterm, Final)

newgrades
#> # A tibble: 6 x 5
#> # Rowwise: 
#>      id TopQuiz NextBestQuiz Midterm Final
#>   <int> <chr>   <chr>        <chr>   <chr>
#> 1     1 0       G            G       G    
#> 2     2 43      0            71      18   
#> 3     3 0       G            G       G    
#> 4     4 0       G            G       G    
#> 5     5 60      38           64      27   
#> 6     6 0       G            G       G

您的数据

grades <- data.frame(
  id = c(1:6),
  Quiz1 = c("0","0","0","0","60","0"),
  Quiz2 = c("G","G","G","G","38","G"),
  Quiz3 = c("G","43","G","G","G","G"),
  Midterm = c("G","71","G","G","64","G"),
  Final = c("G","18","G","G","27","G")
)
`

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM