情况如下。我有data.table
,我想基于某些条件折叠此表的行。我编写了一个函数,但它一次只能运行2行。因此,我可以用一轮函数折叠的最多行是50%(即从1000行开始,函数的第1轮离开我们500)。在这一点上,似乎逻辑上要做的是在生成的输出上再次运行该函数,以便我可以进一步折叠行,然后再次执行此操作,并再次执行此操作,直到我折叠了所有可能的行。 / p>
我的功能
fun = function(x) {
<stuff the function does>
return(output) }
我想在自己的输出上调用该函数,并重复此操作,直到输出不再通过进一步的函数调用而改变。
我试过这个:
fun = function(x) {
<stuff>
output = resulting_dt
while (!identical(x,output)) {fun(output)}
return(output)
}
但这给了我一个错误:
Error in eval(expr, envir, enclos) : object '__' not found
我确信有一种方法可以使这项工作,但我对R编程相当新,这是我必须编写的第一个真正的程序,所以非常感谢任何帮助或建议!
fun = function(x) {
<stuff>
output = resulting_dt
if (!identical(x,output)) {return(Recall(output))}
else {return(output)}
}
对于那些对可重现的功能感兴趣的人,我遇到了一个问题(这是永远的),所以这是我实际使用的一个很难看的功能:
fun <- function (object)
{
num = 1
n = 1
temp = list()
while (n <= object[, length(chr)])
{
if ( (n == (object[, length(chr)])) &&
!( (object[n,chr] == object[n-1,chr]) &&
(abs(object[n,end] - object[n-1,start]) < 500) &&
(((object[n,meth.diff] >= 0) == (object[n-1,meth.diff] >= 0)) ||
((object[n,meth.diff] < 0) == (object[n-1,meth.diff] < 0)))))
{
x = data.table(
chr=object[n,chr], start=object[n,start], end=object[n,end],
meth.diff=object[n,meth.diff], mean_KO=object[n,mean_KO],
mean_WT=object[n,mean_WT], coverage_KO=object[n,coverage_KO],
coverage_WT=object[n,coverage_WT]
)
temp[[num]] = x
n = n + 1
num = num + 1
}
else if ( (object[n,chr] == object[n+1,chr]) &&
(abs(object[n,end] - object[n+1,start]) < 500) &&
(((object[n,meth.diff] >= 0) == (object[n+1,meth.diff] >= 0)) ||
((object[n,meth.diff] < 0) == (object[n+1,meth.diff] < 0))))
{
x = data.table(
chr=object[n,chr], start=object[n,start], end=object[n+1, end], meth.diff= mean(c(object[n,meth.diff], object[n+1,meth.diff])),
mean_KO=(((object[n,mean_KO] * object[n,coverage_KO])/(object[n,coverage_KO] + object[n+1,coverage_KO])) +
((object[n+1,mean_KO] * object[n+1,coverage_KO])/(object[n,coverage_KO] + object[n+1,coverage_KO]))),
mean_WT=(((object[n,mean_WT] * object[n,coverage_WT])/(object[n,coverage_WT] + object[n+1,coverage_WT])) +
((object[n+1,mean_WT] * object[n+1,coverage_WT])/(object[n,coverage_WT] + object[n+1,coverage_WT]))),
coverage_KO=(object[n,coverage_KO] + object[n+1,coverage_KO]),
coverage_WT=(object[n,coverage_WT] + object[n+1,coverage_WT])
)
x[, meth.diff := (mean_KO - mean_WT) ]
temp[[num]] = x
n = n + 2
num = num + 1
}
else
{
x = data.table(
chr=object[n,chr], start=object[n,start], end=object[n,end],
meth.diff=object[n,meth.diff], mean_KO=object[n,mean_KO],
mean_WT=object[n,mean_WT], coverage_KO=object[n,coverage_KO],
coverage_WT=object[n,coverage_WT]
)
temp[[num]] = x
n = n + 1
num = num + 1
}
}
result = rbindlist(temp)
#print(result)
while (!identical(object,result)){fun(result)}
else {return(result)}
}
AND示例输入data.table:
library(data.table)
dt = structure(list(chr = c("chr1", "chr1", "chr1", "chr1", "chr1",
"chr1", "chr1", "chr1", "chr1", "chr1"), start = c(842326, 855423,
855426, 855739, 855771, 880164, 880182, 880262, 1005284, 1005315
), end = c(842327L, 855424L, 855427L, 855740L, 855772L, 880165L,
880183L, 880263L, 1005285L, 1005316L), meth.diff = c(9.35200555410902,
19.1839617944039, 29.6734426495636, -12.3375577709254, 4.21809779410175,
50.539925536006, 28.0168014922334, 35.1349192165154, 16.8742940741475,
62.6063420676512), mean_KO = c(9.35200555410902, 19.1839617944039,
32.962962583692, 1.8512250859083, 4.44417336983763, 67.0864799025607,
31.1083297690512, 49.5746020684321, 25.1985773481452, 78.6766354515961
), mean_WT = c(0, 0, 3.28951993412841, 14.1887828568337, 0.226075575735883,
16.5465543665547, 3.09152827681786, 14.4396828519167, 8.32428327399768,
16.0702933839448), coverage_KO = c(139L, 55L, 55L, 270L, 270L,
55L, 55L, 238L, 526L, 499L), coverage_WT = c(120L, 86L, 87L,
444L, 442L, 116L, 115L, 362L, 649L, 647L)), .Names = c("chr",
"start", "end", "meth.diff", "mean_KO", "mean_WT", "coverage_KO",
"coverage_WT"), class = c("data.table", "data.frame"), row.names = c(NA,
-10L))
和我想要的输出的一个例子(对于后代,因为它与这个问题不完全相关)
library(data.table)
dt1 = structure(list(chr = c("chr1", "chr1", "chr1", "chr1", "chr1",
"chr1"), start = c(842326, 855423, 855739, 855771, 880164, 1005284
), end = c(842327L, 855427L, 855740L, 855772L, 880263L, 1005316L
), meth.diff = c(9.35200555410902, 24.4191949389371, -12.3375577709254,
4.21809779410175, 36.7726824955192, 39.0419497750433), mean_KO = c(9.35200555410902,
26.073462189048, 1.8512250859083, 4.44417336983763, 49.4237638627169,
51.2332612443618), mean_WT = c(0, 1.65426725011082, 14.1887828568337,
0.226075575735883, 12.6510813671977, 12.1913114693185), coverage_KO = c(139L,
110L, 270L, 270L, 348L, 1025L), coverage_WT = c(120L, 173L, 444L,
442L, 593L, 1296L)), .Names = c("chr", "start", "end", "meth.diff",
"mean_KO", "mean_WT", "coverage_KO", "coverage_WT"), row.names = c(NA,
-6L), class = c("data.table", "data.frame"))
答案 0 :(得分:3)
这是?Recall
fib <- function(n)
if(n<=2) { if(n>=0) 1 else 0 } else Recall(n-1) + Recall(n-2)
> fib(10)
[1] 55
答案 1 :(得分:1)
这听起来像returnValue
和on.exit
函数的任务。你没有提供可重复的例子,所以我不会为你想象一个
可以在我的dtq包中找到returnValue
的工作示例。它用于记录任意函数返回的对象行数
必须在returnValue
内使用on.exit
,请参阅dtq/R/zzz.R#L23:
on.exit(
dtq.local.log(
timestamp = Sys.time(),
end = if(isTRUE(getOption("dtq.log.nano")) && requireNamespace("microbenchmark", quietly=TRUE)) microbenchmark::get_nanotime()*1e-9 else proc.time()[[3L]],
out_rows = as.integer(nrow(returnValue()))[1L]
)
)
# hint on: as.integer(.)[1L]
# is used to return NA for object for which `nrow` will not make sense
# so to ensure length 1 integer type object is returned
请注意,此功能最近在基础R中引入,因此如果您使用旧版本的R,则可能无法找到它。