我是新编程和R所以如果我在这个问题上不够清楚,我会道歉。我认为我的问题有两个问题。我首先尝试给出一些背景信息。一,我的数据框中有一个数据框:
'data.frame': 27609 obs. of 2 variables:
$ Diff : num 2557 2038 0 30 0 ...
$ freq.:'data.frame': 27609 obs. of 1 variable:
..$ freq: int 85 68 1 31 1 35 1 1 34 42 ...
> head(d.f.)
Diff freq
1 2557 85
2 2038 68
3 0 1
4 30 31
5 0 1
6 1034 35
我认为这会导致我的后续问题mapply()在哪里 我想应用一个函数,在每一行中,从一列中取值,除以另一列中的值,然后输出1,2,3或4,具体取决于商所在的值的范围英寸
myFunction = function(a,b) {
interval = (a/b)
ifelse(interval==0, 1 ,
ifelse(interval<1, 2 ,
ifelse(interval<31, 3 , 4)))}
Test = mapply(myFunction, d.f.$Diff, d.f.$freq)
> Test
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 3 3 1 2 1 3
[2,] 4 3 1 2 1 3
[3,] 4 4 1 3 1 4
[4,] 4 4 1 2 1 4
[5,] 4 4 1 3 1 4
[6,] 4 4 1 2 1 3
上面,测试仅在前6行上运行。 最终发生的事情是Test需要永远在整个d.f.运行。并且由于某种原因最终输出矩阵,其中我感兴趣的唯一值在第一行中。我真的很感激帮助我理解我做错了什么。提前谢谢!
答案 0 :(得分:2)
你的功能是矢量化的:
myFunction(df$Diff, df$freq)
[1] 3 3 1 2 1 3
您可以直接创建新列。
df$newcol <- myFunction(df$Diff, df$freq)
答案 1 :(得分:2)
你在这里重新发明轮子。虽然ifelse
是矢量化的,但众所周知它是not the sharpest pencil in drawer。当然,嵌套它们通常是一个坏主意。相反,您具有非常高效的cut
和findInterval
功能,专门为此类任务而设计。这是一个示例用法
myFunc2 <- function(a, b) {
tol <- .Machine$double.eps
findInterval(a/b, c(0, 0 + tol, 1, 31 - tol, Inf))
}
这里有一些速度比较(你获得x20加速)
set.seed(123)
df <- data.frame(Diff = sample(1e3, 1e8, replace = TRUE),
freq = sample(1e2, 1e8, replace = TRUE))
system.time(res <- with(df, myFunction(Diff, freq)))
# user system elapsed
# 40.36 18.63 611.18
system.time(res2 <- with(df, myFunc2(Diff, freq)))
# user system elapsed
# 1.89 0.83 76.64
identical(as.integer(res), res2)
# [1] TRUE
答案 2 :(得分:-1)
如果您将其变为data.table
(并调用变量dt
):
> dt[, interval := Diff / freq]
> dt[, ifelse(interval == 0, 1, ifelse(interval < 1, 2, ifelse(interval < 31, 3, 4)))]
[1] 3 3 1 2 1 3