一、题目回顾

 )



二、算法流程

Step 1: 输入要点名的人数\(Num\),和名单数据集\(Data\).

Step 2: 名单数据集中是否存在”姓名“栏? 若存在:转向Step 3. 否则:输出 “名单中没有“姓名”栏,请检查数据!”.

Step 3: 点名人数\(Num\)是否超出名单人数? 若没有超出:转向Step 4. 若超出:输出 “名单中最多有n个人,请重新输入点名人数!”.

Step 4: 生成随机数\(Sign\sim N\left( 0,1 \right)\)作为每个人的记号数 将名单里所有人的记号数降次排列,选择其中最大的\(Num\)个记号数,他们对应的人是被点名者

Step 5: 判断\(Num\)个记号数是否有重复? 若没有重复:将被点名者数据转化为字符型,输出. 若重复:转向Step 4.



三、函数使用说明

1. 函数功能

RandCall( )函数用于随机点名。


2. 输入输出

输入参数

  • Num: 需要点名的人数,数据类型:int
  • Data: 点名名单数据框,数据类型:data.frame

输出结果

  • 数据错误:提供的数据框中没有”姓名“栏,无法实现点名功能。
  RandCall(5,Data2)
## [1] "名单中没有“姓名”栏,请检查数据!"


  • 点名人数超出范围:输入需要点名的人数超出了数据框名单中的人数,无法实现要求的点名功能。
  RandCall(20,Data)
## 名单中最多有 15  个人,请重新输入点名人数!


  • 正常输出:输出Num个随机点名的人的姓名
  RandCall(5,Data)
## [1] "史可馨"        "艾力西尔·艾力" "唐业儒"        "徐欧"         
## [5] "叶子傲"



四、函数结果演示

  RandCall(1,Data)
## [1] "张昱葳"


  RandCall(5,Data)
## [1] "史可馨"   "扎西旺堆" "刘泽全"   "昂旺桑丁" "唐业儒"



六、RandCall( )主要代码

  RandCall <- function(Num,Data){
  n <- nrow(Data)
  if("姓名"%in%colnames(Data)){
  if(Num<=n){
    
    while(1){#避免重复点名
    Sign <- runif(n)#为名单中的每个人分配一个服从U(0,1)的随机数
    Data1 <- cbind(Data,Sign)
    SelStud <- Data1[order(Data1$Sign,decreasing = T),][c(1:Num),]$'姓名' #抽取分配随机数中最大的Num个人
    SelStud <- as.character(SelStud)#化为字符型
    
    if(length(unique(SelStud))==Num){
      break
    }
    
    }
    return(SelStud)#输出点名的人
    
  }else{
    
    cat('名单中最多有',n,' 个人,请重新输入点名人数!')
    
  }
  }else{
    
    return('名单中没有“姓名”栏,请检查数据!')
  }
}