一直看老大代码看得觉得可痛快了呢,刷刷地结果就出来了,到自己想做个芝麻大点儿的事,头发抓掉一大把,都弄不出来。有些时候,以为懂和会,只是没实际去用,等真到自己上手,用那个网络语形容-啥也不是。不墨迹啦,记录下。
主要是想改一个表达矩阵里,那些小于0的数值变为0。变成apply和function的事情了,我是真的不会用。
> #下面三行代码就是前两行觉得没问题呀,第三行就是不对,哎
> dat[8,][dat[8,]< -1] <- 0
> dat[9,][dat[9,]< -1] <- 0
> apply(dat,1,function(x){x[x< -1] <- 0})
> #问老大,一行代码搞定。就是下面这个。
> dat[dat<0]=0
新建一个小数据模拟上面的代码的问题
> mm<- data.frame(aa=seq(1:5),
+ bb=c(4,5,0,1,2),
+ cc=rep(1,5))
>
> mm
aa bb cc
1 1 4 1
2 2 5 1
3 3 0 1
4 4 1 1
5 5 2 1
> #用了下面的两个函数,其实意思和前面的是一样的,结果依然是不对的。
> apply(mm,1,function(x){x[x< 2] <- 'zz'})
[1] "zz" "zz" "zz" "zz" "zz"
> apply(mm,2,function(x){x[x< 2] <- 'zz'})
aa bb cc
"zz" "zz" "zz"
>
上面的结果肯定不对,得再想想,搜索到一个很好的例子,其实之前也见过
> #还是得回去再理解一下了。
> ##################### 点石举例 ##########################
> #http://www.crickcollege.com/news/236.html
> l1 <- c(4,9,16)
> l2 <- c(25,36,49)
> matrix <- cbind(l1,l2)
> matrix_apply1 <- apply(matrix,1,sum)
> matrix_apply1
[1] 29 45 65
> matrix_apply2 <- apply(matrix,2,sum)
> matrix_apply2
l1 l2
29 110
> matrix_apply3 <- apply(matrix,1,sqrt)
> matrix_apply3
[,1] [,2] [,3]
l1 2 3 4
l2 5 6 7
> matrix_apply4 <- apply(matrix,2,sqrt)
> matrix_apply4
l1 l2
[1,] 2 5
[2,] 3 6
[3,] 4 7
> #自定义函数(有一个自变量)
> #将sqrt变为 function(x) MyFunction(x)。这一写法翻译成中文是,应用一个自变量为x的函数,这个函数(我之前定义过,起了名字)叫MyFunction,矩阵里的每一个元素(按照运算顺序)都是x。
> myfun1 <- function(x){
+ result <- 1+sqrt(x)
+ return(result)
+ }
> #结果成行
> matrix_apply5 <- apply(matrix,1, function(x) myfun1(x))
> matrix_apply5
[,1] [,2] [,3]
l1 3 4 5
l2 6 7 8
> #结果成列
> matrix_apply6 <- apply(matrix,2, function(x) myfun1(x))
> matrix_apply6
l1 l2
[1,] 3 6
[2,] 4 7
[3,] 5 8
> #有两个自变量(有两个自变量)
> myfun2 <- function(x,y){
+ result <- sqrt(x)+y
+ return(result)
+ }
> matrix_apply7 <- apply(matrix,1, function(x) myfun2(x,10))
> matrix_apply7
[,1] [,2] [,3]
l1 12 13 14
l2 15 16 17
>
> matrix_apply8 <- apply(matrix,2, function(x) myfun2(x,10))
> matrix_apply8
l1 l2
[1,] 12 15
[2,] 13 16
[3,] 14 17
>
> matrix_apply9 <- apply(matrix,1, function(y) myfun2(100,y))
> matrix_apply9
[,1] [,2] [,3]
l1 14 19 26
l2 35 46 59
>
> matrix_apply10 <- apply(matrix,1, function(y) myfun2(100,y))
> matrix_apply10
[,1] [,2] [,3]
l1 14 19 26
l2 35 46 59
>
> #返回这个新建的小数据mm。
> mm
aa bb cc
1 1 4 1
2 2 5 1
3 3 0 1
4 4 1 1
5 5 2 1
>
> #尝试(1)
> fun1<- function(x){
+ 'zz' <- x<1
+ return(x)
+ }
>
> apply(mm,2,function(x)fun1(x))
aa bb cc
[1,] 1 4 1
[2,] 2 5 1
[3,] 3 0 1
[4,] 4 1 1
[5,] 5 2 1
>
> #尝试(2)
> fun2 <- function(x){
+ 'zz' <- x[x<1]
+ return(x)
+ }
> apply(mm,2,function(x)fun2(x))
aa bb cc
[1,] 1 4 1
[2,] 2 5 1
[3,] 3 0 1
[4,] 4 1 1
[5,] 5 2 1
>
> #尝试(3)
> fun3 <- function(x){
+ x[x<1] <- 'zz'
+ return(x)
+ }
> apply(mm,2,function(x)fun3(x))
aa bb cc
[1,] "1" "4" "1"
[2,] "2" "5" "1"
[3,] "3" "zz" "1"
[4,] "4" "1" "1"
[5,] "5" "2" "1"
> apply(mm,1,function(x)fun3(x))
[,1] [,2] [,3] [,4] [,5]
aa "1" "2" "3" "4" "5"
bb "4" "5" "zz" "1" "2"
cc "1" "1" "1" "1" "1"
>
>
>
> #尝试(4)如果不加return呢?
> fun4 <- function(x){
+ x[x<1] <- 'zz'
+ }
> apply(mm,2,function(x)fun4(x))
aa bb cc
"zz" "zz" "zz"
> #不加return就不行了,所以按照之前的写法如下,就不对
> apply(mm,2,function(x){x[x<1] <- 'zz'})
aa bb cc
"zz" "zz" "zz"
> #那么我思考的是,如果想要的结果是为了返回一个新生成的值,就要加一个return,这个return可以返回要的值
> #尝试(5) 下面一句就轻松搞定了,是老大发给我的。
> nn <- mm
> nn[nn<1]='zz'
>
但是还是不是理解,就把老大最近一篇公众号上的用了function函数看看,再理解下。
> #https://mp.weixin.qq.com/s/qS0z23mMxJYpGfOvsO_TIQ
> set.seed(123)
> dat=data.frame(s1=rnorm(26),
+ s2=rnorm(26),
+ s3=rnorm(26),
+ s4=rnorm(26))
> rownames(dat)=LETTERS
> dat['A',]
s1 s2 s3
A -0.5604756 0.837787 -0.04287046
s4
A 0.1813035
> pos=match(c('D','G','Z'),rownames(dat))
> apply(dat, 2, function(x){
+ order(x,decreasing = T)[pos]
+ })
s1 s2 s3 s4
[1,] 11 7 24 12
[2,] 7 9 6 6
[3,] 18 17 20 22
>
> #上面的这个function函数和apply函数我能不能按照刚才的步骤再拆一下,然后理解结果是要干什么
> #
> myfun11 <-function(x){
+ order(x,decreasing = T)[pos]
+ }
> apply(dat,2,function(x)myfun11(x))
s1 s2 s3 s4
[1,] 11 7 24 12
[2,] 7 9 6 6
[3,] 18 17 20 22
> #上面的重新定义了一个myfun11以后,得到的这个结果也是能够运行出和老大直接apply(dat, 2, function(x){order(x,decreasing = T)[pos]})一样的结果的,是不是可以理解成,如果我要是想要新替换已有变量的时候,就一定要定义为一个变量,如果仅仅是输出一个结果就不用必须新定义一个变量了。或许我理解的也不对。
> #上面的理解:我用function函数定义了一个myfun11函数,x是这个myfun11函数里面的变量,这个里面的x,指代的应该是dat里每一列中所有的元素。这个order是可以和sum函数类似的道理,可以用在对多个元素的处理上。
>
再翻一个例子
> #https://mp.weixin.qq.com/s/XQybC6W0aLrbyzHNvJnDvA
> mycal<-function(x){
+ mean<-mean(x)
+ sd<-sd(x)
+ result <- list(mean=mean,sd=sd)
+ return(result)
+ }
> x<-c(1,2,3,80)
> mycal(x)
$mean
[1] 21.5
$sd
[1] 39.00855
>
> mysave<-function(earn,spend,lost){
+ save<- earn-spend-lost
+ result <- list(save=save)
+ return(result)
+ }
> mysave(earn = 1000,spend = 80,lost = 10)
$save
[1] 910
>
> myscore<-function(paper,attendence){
+ score<- paper*0.7+attendence*.3
+ result <- list(score=score)
+ return(result)
+ }
> myscore(paper = 92,attendence = 70)
$score
[1] 85.4
还有很好的在代码的例子,再体会一下,技能树的推文里很多。我现在的理解是:这里function(x)里的x不和apply一起用的时候,就是可以是任意变量,可以是单个元素也可以是整体数据;如果是和apply函数一起用,代表的是那一行或那一列的所有元素。理解的可能不对,迷糊中,掐掉,只是记录。
参考: