【发布时间】:2019-07-05 12:59:15
【问题描述】:
序言
我提前道歉,我发现很难用书面形式表达确切的问题,并且认为通过查看代码最清楚。另外,我对 R 比较陌生,并且无法使用正确的词来准确描述这种情况。我认为解决方案应该很容易被有更多经验的人指出,任何建议都将不胜感激!
说明
我有一个专门的计算,我试图逐个组进行计算,为此我编写了一个函数。该函数是用户定义的来执行这个专门的计算,需要 4 个参数(其中 2 个的长度 >1)并输出一个值(所以输出不等于输入的长度)。虽然此功能确实有效,但我需要能够有效地将其应用于数据框中的每个组(对于下面的可重现示例,有 4 个组,但实际上,将有 100 或 1000 个组)。
我尝试使用 apply 函数,通常推荐用于听起来与此类似的情况,但到目前为止我在使用非 for 循环方法方面并不成功。我认为这是因为数据框中的每一行都没有与不同的组相关联,而是有多个行与单个组相关联(对于下面的可重现示例,每个组有 21 行相关联,这与实际数据)。
无论如何,for 循环似乎是将我的函数应用于与每个组关联的行的一种直接方法。但是,我无法生成所需的输出。正如我在序言中提到的那样,我认为这只是因为我忽略/没有意识到一些非常基本的事情,例如需要在循环内执行循环或以不同方式索引我的 for 循环。
可重现的示例
功能相似的数据
interval=0.05 #used here to generate v1 and again in the function
v1 = seq(0.00000000001,1.00000000001, by=interval)
nrows = length(v1) #determines length of other variables
g1 = c(rep(23.4, nrows), rep(19.7, nrows),rep(25.2, nrows),rep(16.4,
nrows))
v2 = runif(length(g1), 0,1)
dat = as.data.frame(cbind(g1,v1,v2))
地点:
- g1是分组变量
- v1 是第一个参数,对每个分组变量重复
- v2是第二个参数,表示与每个v1相关的概率
- dat 是数据框
函数
(这是我的第一个函数,我认为有更好的方法来编写它,但它确实有效)
MyFunction = function(v1, v2, interval, nrows) {
sum.prod = sum(v1[2:nrows-1] * v2[2:nrows-1])
last.val = v2[nrows]/2
out = 2 * (sum.prod+last.val) * interval
out
}
证明该功能有效
我提供了第一个分组变量 (g1=23.4) 的计算,以防万一有助于确认该函数是否有效以及它是如何工作的,因为没有此函数的文档
range1 = 1:nrows
g1.sub1 = dat$g1[range1]
v1.sub1 = dat$v1[range1]
v2.sub1 = dat$v2[range1]
g.first = 2 * ((v1.sub1[2] * v2.sub1[2])+
(v1.sub1[3] * v2.sub1[3]) + (v1.sub1[4] * v2.sub1[4]) +
(v1.sub1[5] * v2.sub1[5]) + (v1.sub1[6] * v2.sub1[6]) +
(v1.sub1[7] * v2.sub1[7]) + (v1.sub1[8] * v2.sub1[8]) +
(v1.sub1[9] * v2.sub1[9]) + (v1.sub1[10] * v2.sub1[10]) +
(v1.sub1[11] * v2.sub1[11]) + (v1.sub1[12] * v2.sub1[12]) +
(v1.sub1[13] * v2.sub1[13]) + (v1.sub1[14] * v2.sub1[14]) +
(v1.sub1[15] * v2.sub1[15]) + (v1.sub1[16] * v2.sub1[16]) +
(v1.sub1[17] * v2.sub1[17]) + (v1.sub1[18] * v2.sub1[18]) +
(v1.sub1[19] * v2.sub1[19]) + (v1.sub1[20] * v2.sub1[20]) +
v2.sub1[21] / 2) * interval
g.first
与以下给出的值匹配:
MyFunction(v1 = v1.sub1, v2 = v2.sub1, interval = interval, nrows=nrows)
我被卡住的地方:For 循环
正如我在描述中提到的那样,我尝试了各种方法来解决这个问题,包括应用函数系列,但没有运气。下面的代码代表了我最接近的。但是,这只给了我四次 g1 (23.4) 中的第一个元素的正确值,而不是 g1 (23.4, 19.9.25.2,16.4) 中的四个元素中的每一个的正确值。
g=c(unique((g1)))
out=NULL
for(i in seq_along(g)){
out[i]=MyFunction( v1 = v1, v2 = v2, interval = interval, nrows =
nrows)
}
out
尝试对 For 循环进行故障排除
我可以强制上述 for 循环产生类似于所需结果的结果,但必须为每个组指定范围,因为实际数据有 100 个组而不是 4 个组,并且组的总数不是事先知道这不是一个可行的解决方案。
g=c(unique((g1)))
range1 = 1:nrows
range2 = (nrows+1):(nrows*2)
range3 = (nrows*2+1):(nrows*3)
range4 = (nrows*3+1):(nrows*4)
out1=NULL
out2=NULL
out3=NULL
out4=NULL
for(i in seq_along(g)){
out1[i]=MyFunction( v1 = dat$v1[range1], v2 = dat$v2[range1],
interval = interval, nrows = nrows)
out2[i]=MyFunction( v1 = dat$v1[range2], v2 = dat$v2[range2],
interval = interval, nrows = nrows)
out3[i]=MyFunction( v1 = dat$v1[range3], v2 = dat$v2[range3],
interval = interval, nrows = nrows)
out4[i]=MyFunction( v1 = dat$v1[range4], v2 = dat$v2[range4],
interval = interval, nrows = nrows)
}
out1
out2
out3
out4
所需的输出
理想情况下,最终输出将是一个表格/矩阵/列表/数据框,其中包含 g1 的每个值以及函数“out”输出的相关值
类似:
g1 out
23.4 some value between 0 and 1
19.9 some value between 0 and 1
25.2 some value between 0 and 1
16.4 some value between 0 and 1
结论性思考
由于我的“For 循环故障排除尝试”最终能够提供正确的输出,尽管是以一种不合需要的方式(劳动密集型,不可扩展,并且它为每组输出 4 个相同的值,而不是为每组输出 1 个值),我认为这表明我的代码缺少一些基本的东西(例如,另一个循环、seq_along 的不同变量、不正确的索引等)。我希望这对于更有经验的用户来说很容易识别和解释,因为我很难过。
提前致谢!
【问题讨论】:
标签: r for-loop indexing subset scalability