我不是真正的懂apply和function,或许压根儿没懂过

一直看老大代码看得觉得可痛快了呢,刷刷地结果就出来了,到自己想做个芝麻大点儿的事,头发抓掉一大把,都弄不出来。有些时候,以为懂和会,只是没实际去用,等真到自己上手,用那个网络语形容-啥也不是。不墨迹啦,记录下。

主要是想改一个表达矩阵里,那些小于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函数一起用,代表的是那一行或那一列的所有元素。理解的可能不对,迷糊中,掐掉,只是记录。

参考:

?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容