簡體   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