【发布时间】:2016-02-20 20:58:06
【问题描述】:
我有一些由类似振荡的模式组成的数据,我想对峰值进行一些测量。我有几块代码,其中大多数都可以完全按照我的意愿工作。我遇到的主要问题是我不知道如何将它们集成起来以在功能上协同工作。
基本上,我想使用我在数据帧上编写的 freq 函数,以便它将遍历每一列(a、b 和 c)并给我函数的结果。然后我想将每一列的输出存储在一个新的数据框中,列名与源名称匹配。
我已经阅读了很多关于循环遍历列和在数据框中创建新列的答案,这就是我达到这一点的方式。一些单独的部分需要稍微调整,但我无法在任何地方找到一个很好的解释,说明我如何将它们组合在一起。我试过无济于事;我只是看不到正确的顺序。
(对于可重现的数据)
library(zoo)
count = 1:20
a = c(-0.802776, -0.748272, 0.187434, 1.23577, 1.00677, 0.874122, 0.232802, -0.279368, -1.57815, -1.76652, -0.958916, -0.316385, 0.831575, 1.19312, 1.45508, 0.848923, 0.257728, -0.318474, -1.14129, -1.42576)
b = c(-2.23512, -1.36572, -0.0357366, 0.925563, 1.53282, 0.171045, -0.438714, -1.38769, -0.696898, 1.37184, 2.01038, 2.6302, 2.53296, 1.8788, 0.100366, -1.34726, -1.4309, -1.37271, -0.750669, 0.100656)
c = c(0.749062, 0.0690315, -0.750494, -1.04069, -0.654432, 0.0186072, 0.710011, 0.920915, 1.13075, 0.227108, -0.195086, -0.68333, -0.607532, -0.485424, 0.495913, 0.655385, 0.468796, 0.274053, -0.906834 , 0.321526)
test = data.frame(count, a, b, c)
d = 20:40
这是我编写的代码块,用于检查我指定的任何数据并识别局部峰值,然后从识别的峰值计算一系列事物。它工作得非常好,并且它的功能没有问题(但是,欢迎提出使它更好的建议),只需将它与其余部分放在一起。 我想遍历数据框的列(在下一节中使用 for 循环来完成)并获取每列的 freq 函数的结果
freq = function(x, y, data, w=1, span = 0.05, ...) {
require(zoo)
n = length(y)
y.smooth = loess(y ~ x, span = span)$fitted
y.max = rollapply(zoo(y.smooth), 2*w+1, max, align = "center")
delta = y.max - y.smooth[-c(1:w, n+1-1:w)]
i.max = which(delta <= 0) + w #identifies peaks
list(x = x[i.max], i = i.max, y.hat = y.smooth)
dist = diff(i.max) #calculates distance between peaks
instfreq = (25/dist) #calculates the rate of each peak occurence
print(instfreq) #output I ultimately want
}
#example
freq(count, a, span = 0.5)
这就是我在指定数据框中循环遍历列的方式。另外,我不确定我做了什么,但这最终会打印我的输出两次......(我想避免)。
for(i in test){
output <- freq(test$count, y = i, span = 0.5)
print(output)
}
这可能是让我最头疼的部分。这应该将新列添加到现有数据框中。到目前为止它有效,但我还没有弄清楚如何将它集成到上面的东西中。另外,我真的很希望它将输出存储在一个新的数据帧中,而不是源数据帧中。
作为参考,这里 df = data,to.add = 要添加到 df 的数据,new.name = 新 col 的名称
我想要的另一件事是 new.name 来自源 (to.add)。例如,如果我尝试将 d (从上面)添加到测试的末尾,我希望列名(new.name)读取 d 而不必指定它。当我遍历多个列并希望保留计算输出的源名称时,这将很有帮助。
add.col = function(df, to.add, new.name){
if (nrow(df) < length(to.add)){
df = # pads rows if needed
rbind(df, matrix(NA, length(to.add)-nrow(df), ncol(df),
dimnames = list(NULL, names(df))))
}
length(to.add) = nrow(df) # pads with NA's
df[, new.name] = to.add; # names new col whatever was placed in new.name arg
return(head(df)) #shortened output so I can verify it worked
#when I was testing it for myself, this would
#need to be changed so that it adds the column
#to a dataframe and stores the results, which
#I believe would require I use print() and a store
#like Results = print(df)
}
#example
addcol(test, d, "d") #would like the code to grab the name d just from the to.add
#argument, without having to specify "d" as the new.name
任何帮助、建议或改进(使其不那么笨重、更高效等)将不胜感激。 只要我能弄清楚如何将所有输出一起存储在一个地方,我就可以使用 for 循环(如果重复项得到修复)。我的实际数据的格式与上面的可重现集类似,只是有更多的行和列(并且已经在 .csv 数据帧中,而不是从单个向量创建)。
这几天我一直在努力解决这个问题,并且已经到了这么远,但就是无法完全理解。
此外,您还可以随意编辑标题,以帮助它找到合适的人!
【问题讨论】:
标签: r function loops dataframe user-defined-functions