向量化我的思维:R中的向量运算
所以之前我回答了我自己关于在R中思考向量的问题。但现在我有另一个问题,我不能“向量化”。我知道向量更快,循环更慢,但我不知道如何在向量方法中做到这一点: 我有一个数据框架(出于情感原因,我喜欢将其称为我的.data),我想对其进行全面的边际分析。我需要一次删除一个特定的元素并对数据帧进行“赋值”,然后我需要通过只删除下一个元素再次进行迭代。然后再做一次。。。再一次。。。我们的想法是对我的一部分数据进行全面的边际分析。无论如何,我无法想象如何以一种有效的方式做到这一点 我缩短了代码的循环部分,它看起来像这样:向量化我的思维:R中的向量运算,r,vector,R,Vector,所以之前我回答了我自己关于在R中思考向量的问题。但现在我有另一个问题,我不能“向量化”。我知道向量更快,循环更慢,但我不知道如何在向量方法中做到这一点: 我有一个数据框架(出于情感原因,我喜欢将其称为我的.data),我想对其进行全面的边际分析。我需要一次删除一个特定的元素并对数据帧进行“赋值”,然后我需要通过只删除下一个元素再次进行迭代。然后再做一次。。。再一次。。。我们的想法是对我的一部分数据进行全面的边际分析。无论如何,我无法想象如何以一种有效的方式做到这一点 我缩短了代码的循环部分,它看
for (j in my.data$item[my.data$fixed==0]) { # <-- selects the items I want to loop
# through
my.data.it <- my.data[my.data$item!= j,] # <-- this kicks item j out of the list
sum.data <-aggregate(my.data.it, by=list(year), FUN=sum, na.rm=TRUE) #<-- do an
# aggregation
do(a.little.dance) && make(a.little.love) -> get.down(tonight) # <-- a little
# song and dance
delta <- (get.love) # <-- get some love
delta.list<-append(delta.list, delta, after=length(delta.list)) #<-- put my love
# in a vector
}
for(j in my.data$item[my.data$fixed==0]){#这不是答案,但我想知道是否有任何洞察在这个方向上:
> tapply((my.data$item[my.data$fixed==0])[-1], my.data$year[my.data$fixed==0][-1], sum)
tapply生成一个统计表(本例中为总和;第三个参数),根据作为第二个参数给出的参数进行分组
2001 2003 2005 2007
1 3 5 7
[-1]表示法从所选行中删除一行。因此,您可以循环并在每个循环上使用[-i]
for (i in 1:length(my.data$item)) {
tapply((my.data$item[my.data$fixed==0])[-i], my.data$year[my.data$fixed==0][-i], sum)
}
请记住,如果您有任何年份只有一个观察值,则连续的tapply调用返回的表的列数将不相同。(即,如果您退出2001年的唯一观察值,那么2003、2005和2007年将只返回te列).这里是另一种生成和的非常R型的方法。生成一个与输入向量一样长的向量,只包含n个元素的重复和。然后,从和向量中减去原始向量。结果是:一个向量(isums),其中每个条目都是原始向量减去第i个元素
> (my.data$item[my.data$fixed==0])
[1] 1 1 3 5 7
> sums <- rep(sum(my.data$item[my.data$fixed==0]),length(my.data$item[my.data$fixed==0]))
> sums
[1] 17 17 17 17 17
> isums <- sums - (my.data$item[my.data$fixed==0])
> isums
[1] 16 16 14 12 10
>(my.data$item[my.data$fixed==0])
[1] 1 1 3 5 7
>总和
[1] 17 17 17 17 17
>isums isums
[1] 16 16 14 12 10
奇怪的是,学习R中的矢量化帮助我习惯了基本的函数编程。一种基本技术是将循环中的操作定义为函数:
data = ...;
items = ...;
leave_one_out = function(i) {
data1 = data[items != i];
delta = ...; # some operation on data1
return delta;
}
for (j in items) {
delta.list = cbind(delta.list, leave_one_out(j));
}
delta.list = sapply(items, leave_one_out);
要进行矢量化,只需将for
循环替换为sapply
映射函数:
data = ...;
items = ...;
leave_one_out = function(i) {
data1 = data[items != i];
delta = ...; # some operation on data1
return delta;
}
for (j in items) {
delta.list = cbind(delta.list, leave_one_out(j));
}
delta.list = sapply(items, leave_one_out);
这很好地提醒了我如何以r式的方式思考。在我的应用程序中,求和后的步骤似乎给我在应用你提到的方法时带来了一些问题。但我投票了这个,以便给你一些声誉分数。我很高兴在这里看到另一个r人!@joran:编辑一个30个月的问题一定会有奖(:)可能是某个版本的亡灵巫师?好主意。我在想一些类似自然历史博物馆馆长的东西可能不会那么病态。或者可能是侏罗纪公园?我只是震惊这个问题持续了三年,没有人对速度部分发表评论。矢量化通常会提高速度,但并不总是如此;可读性“不确定性通常是更重要的原因。@gsk3,请记住,当我最初问这个问题时,只有大约5个人在阅读[r]问题:)