一些想说的

这个取决于你希望通过这门语言去达成什么目标。如果只是进修扩展视野,更多的是对语法的思想和数据结构上面找出共同点去修修补补其他自己知识点。
如果是对数据分析感兴趣,那么除了 R 语言之外还需要对数据分析本身进行学习,测试和统计学是不分家的,为什么这么说,让我依次道来。
首先按软件整个过程是分为不同的里程碑版本,能够前往下个版本是有准入标准的,正统学过 PM 的人,知道有一个一个开门(准入)和闭门(允许到下个阶段),抛出几个问题:
1.alpha 版本进入 open beta 需要满足怎么样的数据,剩余问题数量,修复率(需要根据当前研发团队的周期和人力配置等评估)。
2.alpha 任务/bug 的燃尽图应该是新增大于修复,燃尽图是否健康。
3.alpha 任务/bug 的燃尽图二条线的偏移量是否合理,燃尽图吞吐量(某些天处理能力)变大变小是否合理。
4.alpha 当前阶段测试密度如何统计(不同级别问题系数 a+ 不可必现问题系数 b+reopen 数量 * 系数 c)。
5.检查任务是否和缺陷的关联度。

这些也是在指定范围内,去做测试开发范畴内的事情。测试数据是挺重要的,远不止只能计算以上的问题。
可以根据这些问题去定义其他统计的场景(比如:任务和缺陷关联度,模块复杂度和产出问题分类评估,reopen 问题数量和模块分布等),最终去计算出隐藏未找到的问题可能会集中在哪些模块和哪些开发者手上,为的就是在上线之前把问题尽可能找到。
如果用脚本语言(例如 Python)去开发(自己定义模型/以及 data.frame 的数据结构去计算拟合)或者人工统计,难度和成本是不小的,R 语言作为一个 DSL 语言,可以去分析评估生物,国民经济等的,来做数分是真正意义上的术有专攻。

里面一些例子,用 R 也基本实现了,后面一点点展开。
测试是各行各业中众多混合型技能的岗位之一,是大是小,取决于自己对这个岗位的基本态度。

讲完列表后,会进入列表的课题:
玩家的数据"注册"进入到列表,展示列表数据,然后对列表内容转换成向量。
回归 data.frame 进行创建一些数据。

列表

列表在语言层面来看是一个可以扩容的容器,R 语言没有去了解过是否内部长度多少,可以存储各种数据结构。
列表里面的长度是按列表第一层来看的,如果第二层包含内部的对象有 3 个。
取出来的公式结构就是 列表对象 [[2]] 里面就有 3 个元素,如果里面只有一个元素的,也可以用 [],推荐统一用 [[数字]] 这样无错。

#看打印的东西看到[[索引]],从这个里面
l1 <- list("a","b",c(1:6),matrix(c(LETTERS[1:6]),nrow=2),100,50)
print(length(l1))
print(l1[[3]][2])
print(l1[[4]])

试试打印里面的数据,然后写个函数去美化列表给个名称。
如果不好理解可以理解为列表每个位置加了个 title 作为 key,原来的列表具体内容的 value 就是列表 [[数字]] 去访问,现在可以通过 title 去访问了,三个点代表不定长参数。

setNames <- function(vlist,...){
    names(vlist) <- c(...)
    print(vlist)
    return(vlist)
}

下面调用 setNames() 方法,传入不定长的参数,定义了列表的名称后,可以通过 $ 定义列表名字去访问。

data.list <-setNames(l1,"num1","num2", "num3","num4","num5","num6")
print(paste0("num5:",data.list$num5))
#之前的output:
$num5
[1] 100
打印data.list$num5后
[1] "num5:100"

看看列表是如何做添加的,介绍一种特色写法。

#添加数据,向量需要2个单位
l1[7:8] = c("cat01","cat02")
print(l1)

如果是对同一个索引位置去赋值,同个索引值就是修改,新的索引值就是添加。
下面写个函数,包装的对象添加

#添加列表,就是把函数往下丢。
addLists <- function(v,offset,addv){
    idx <-length(v)
    cnt <- 1
    repeat {
        v[idx+cnt] = addv[cnt]
        cnt <- cnt+1
        if(cnt==offset){
            break
        }
    }
    return(v)
}
l1.newdata <- addLists(l1,5,c("cat03","cat04","cat05","cat06"))
print(l1.newdata)

其中里面技巧是 repeat 和一个退出条件 offset 偏移,当一个 cnt==offset 后就触发退出 repeat 事件。
下面是删除列表的对象,下面是写法例子

#idx是不存在的,等于会定义到idx-1的NULL
delList <- function(v,idx){
    v[idx] <- NULL
    return(v)
}
l1.newdata <-delList(l1.newdata,22)
print(l1.newdata)
print(length(l1.newdata))

这样的写法有个问题是,idx 不存在,会定义到 idx-1 的长度,没有被声明对象,打印数据如下:

#... ...
[[19]]
NULL

[[20]]
NULL

[[21]]
NULL

这么写,语义就不一样了,因为 NULL 在 R 里面是没有意义的,比如把索引位置赋值 NULL,等于删除。上面函数写法还增加了原有列表的长度,等于让 NULL 有了意义。
跑下面这段代码时需要注意不调用 delList()。

#删除队列索引位置的数据。<-NULL
delListv1 <- function(v,idx){
    size <-length(v)
    print(size)
    if(idx>=size){
        idx <- size
    }
    v[idx] <- NULL
    return(v)
}
l1.newdata <- delListv1(l1.newdata,22)
print(l1.newdata)

删除了 l1.newdata[12] 数据,因为 l1.newdata 上面 max 位置就是 12。
合并列表就是做列表拼接,按入参的列表去排列顺序,当然总长度是不会变的。

#合并列表函数,不定长...是好东西
mergeList <- function(...){
    res <- c(...)
    return(res)
}
merges <- mergeList(l_1,l1.newdata,l_2)
print(merges) # 合并后的列表
print(length(merges))

addLists 等于是一个 allPush 功能,一次性往后塞多个对象。

# push(),push是往队列后面添加1个数据
list.push <- function(v,data){
    size <- length(v)
    v[size+1] = data
    return(v)
}
m1 <- list.push(merges,"chenziang")
print(m1)

pop 函数,具体看下面进行实现。

# pop()用于移除列表中的一个元素,并且返回该元素的值
list.pop <- function(v,idx){
    size <- length(v)
    if(idx>size){
        idx <-size
    }
    result <- v[idx]
    v[idx] <-NULL  # R语言作用域问题把v[idx]给删除
    return(result)
}
#输出超过长度的就会
popres <- list.pop(m1,16)
print(paste0("16 postion=",popres))

列表支持切片功能,注意支持-1。但是和 python 不一样,不能用 [xx:-xx] 这种的写法

# 最后一个数,push前面塞进去了数据
print(m1[-1])
print(m1[1:4]) #[0]和[1]是一样的。

列表课题

R 语言并不是所有都有必要搞函数式编程,比如下面的,如果特别封装一层反而会让步骤复杂化了。

# 用户列表
user.list<-list(user.server <- "test",user.create_time <- "2021-02-13 22:23",
                user.id <- 10001,
                user.role_name <- "nainiu cat",
                user.pay_scene <- c("fight","guild","park","task"),
                user.level <-50
)
#之前的定义列表名称
setNames <- function(vlist,...){
    names(vlist) <- c(...)
    print(vlist)
    return(vlist)
}
data.list <-setNames(user.list,"server_name","create_time","id","role_name", "pay_scene","level")
print(data.list)
print(unlist(data.list)) #转换成向量元素

c 向量转列表可以用列表包一层,列表转向量是用 unlist(),下面就进行 data.frame 的回顾,数据也是用上面的。

my.dataset<-data.frame(userid=c(10001:10005),
                       user.pay_scene=c("fight","guild","park","task","shop"),
                       iamount=c(100,50,30,60,70))
print(my.dataset)
# 打印列变量名称
print(names(my.dataset))

平时实在没心气去写,感觉新年有时间学习,还是蛮开心的,争取每天一篇。


↙↙↙阅读原文可查看相关链接,并与作者交流