作者locka (locka)
看板R_Language
标题Re: [问题]不使用for改使用apply写法的可能性
时间Wed Mar 25 07:52:19 2020
(同是apply家族爱好者先shout out一下XD)
以前看过版主C大跟其他前辈版友的讨论,结论是 apply 效率并没有比较好
(印象中好像背後都还是用for回圈?!)
不过我觉得向量化(vectorized)是R语言里面很重要的一个特性
也是functional programming跟其他程式语言不一样的地方
我自己也喜欢做for转apply的练习
=== 分隔线 ===
以下的写法只是随便写的(甚至可以说骨子里还是for的逻辑...)
请其他版友分享更好的写法!!
1. cross validation:
1.a 还是用到folds
sapply(1:5,function(i){
testIndexes <- which(folds==i,arr.ind=T)
# 做你想做的事情
# ex: 找测试集的最大值跟训练集的最小值
max_intest <- max(dataset[testIndexes,])
min_intrain <- min(dataset[-testIndexes,])
#回传结果
c(max_intest,min_intrain)
})
其实这个跟for的写法根本换汤不换药XD
1.b 使用split (不要用cut跟folds)
原po原本的方法是先用sample()抽样打乱原始data的顺序後再用cut()指定组别
提供sapply + split的做法:
sapply(split(dataset,1:5),function(x){
test <- x # test dataset
train <- dataset[-as.numeric(row.names(x)),] # train dataset
# 做你想做的
c(max(test),max(train))
})
这个做法直接把dataset分成5份然後将该dataframe传进sapply里
不过须注意这作法取样的顺序跟cut不一样
cut是111..222...333...444..555(各20次)
split是12345...12345...12345...(共20次)
不过因为一开始已经用sample打乱过顺序了,所以个人觉得後面cut或split应该没差
(有错请指正>"<)
2. 偷偷问的小问题
x <- c(2:3)
y <- c(4:8)
sapply(x,function(i){
i*y
})
其实我後来很常用
sapply(x,function(){
....
})
这样的形式写,因为可以省略掉for里面预先指定次数(i)的模式,写起来也更有弹性
不过要注意function()里面不要太多变数,不然效率应该会很差
(但是如何要评估效率我就不会惹...XD)
许愿:
希望可以钓到版上其他大大 ex: celestialgod, andrew43 两个偶像 >///<
※ 引述《empireisme (empireisme)》之铭言:
: 如题
: 最近想手刻实践 cross validtion的算法
: 上网查了一下别人的范例code
: 如下
: x <- runif(100)*10 #Random values between 0 and 10
: y <- x+rnorm(100)*.1 #y~x+error
: dataset <- data.frame(x,y) #Create data frame
: dataset<- dataset[sample(nrow(dataset)),]
: dataset
: #here is the trick
: folds <- cut(seq(1,nrow(dataset)),breaks=5,labels=FALSE)
: folds
: sample(nrow(dataset))
: for(i in 1:5){
: #Segement your data by fold using the which() function
: #这里就是我想问的
: testIndexes <- which(folds==i,arr.ind=TRUE)
: #这里就是我想问的
: testData <- dataset[testIndexes, ]
: trainData <- dataset[-testIndexes, ]
: #Use the test and train data partitions however you desire...
: #必须要在这个步骤去套入model 然後计算MSE
: }
: 他在切traing 和Testing时 使用了 fold的技巧
: 但是这整段有没有可能 不使用for 回圈 而改用apply家族去实现
: 因为真的太喜欢使用apply的简洁了
: 还希望版友回答
: 偷偷问另外一个问题
: 我有一个function s 去计算 x*y
: s<- function(x,y){ x*y }
: s( c(2,3) , c(4,5) )
: 这里我会得到 8 15
: 但其实我想得到的是所有的可能性
: 8,10,12,15
: 请问我要如何在保有 input是 c(2,3) , c(4,5) 下 得到我要的结果呢
: 更甚至在 s ( c(2,3),c(4,5,6,7,8) ) 状况下也可以得到遍历的结果
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.224.210.149 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/R_Language/M.1585093941.A.3E6.html
1F:→ locka: 之前的讨论可以参考这篇 #1ScvIY4l 03/25 08:07
2F:→ andrew43: 用apply系列在分支後的运算若有例外发生比for会小麻烦 03/25 10:23
3F:→ andrew43: 一点,也比使用for难抓虫。之前做10-fold CV的小经验。 03/25 10:25
4F:→ obarisk: 可以看一下 purrr ,有例外处理的方法。不过,没有很推 03/25 11:31
5F:→ empireisme: 太神拉 03/25 13:25
6F:推 VIATOR: 谢谢分享,不过这个情况实在看不出来apply有比loop好 @@ 03/26 08:53
7F:推 VIATOR: apply的优点在於比较简洁,但CV用apply根本没比较简洁 03/26 08:57
8F:→ locka: 从来没有人说apply比较好啊XD 而且也要端看好的定义是什麽 03/26 09:38
9F:→ locka: ,例如说第一种方法其实跟loop一样,而第二种方法不需要预 03/26 09:38
10F:→ locka: 先设定loop几次,我觉得这点就很有用啦~不过我同意CV用appl 03/26 09:38
11F:→ locka: y写没有比较简洁,挑习惯用的就好~ 03/26 09:38
12F:推 VIATOR: 我只是在讨论,如果有冒犯到请多多包涵 03/26 13:36
13F:→ locka: V大客气了~没事没事!请多讨论XD 03/26 13:41