我对R相当陌生,在实现一些本应非常基础的东西时遇到了麻烦。有人可以指出我正确的方向吗?
我需要基于两个向量的值进行逻辑计算,然后在第三个向量中返回该函数的值。
我想在用户定义的函数中执行此操作,因此我可以轻松地将此算法应用到算法的其他几个方面,并轻松修改实现。
这是我尝试过的方法,但是我无法使此实现起作用。我相信是因为我无法将向量作为此函数的参数发送。
<!-- language: python -->
calcSignal <- function(fVector, sVector) {
if(!is.numeric(fVector) || !is.numeric(sVector)) {
0
}
else if (fVector > sVector) {
1
}
else if (fVector < sVector) {
-1
}
else {
0 # is equal case
}
}
# set up data frame
df <- data.frame(x=c("NA", 2, 9, 7, 0, 5), y=c(4, 1, 5, 9, 0, "NA"))
# call function
df$z <- calcSignal(df$x, df$y)
我希望输出是具有以下值的向量,但我没有正确实现该函数。
[0,-1,1,-1,0,0]
有人可以帮助解释如何实现此功能以正确执行概述的逻辑吗?
感谢您的帮助!
答案 0 :(得分:1)
?sign
挺身而出,无需循环播放
# fixing the "NA" issue:
df <- data.frame(x=c(NA, 2, 9, 7, 0, 5), y=c(4, 1, 5, 9, 0, NA))
s <- sign(df$x - df$y)
s[is.na(s)] <- 0
s
#[1] 0 1 1 -1 0 0
答案 1 :(得分:1)
ifelse
是另一个方便的功能。虽然比sign
少优雅
df <- data.frame(x=c(NA, 2, 9, 7, 0, 5), y=c(4, 1, 5, 9, 0, NA))
cs <- function(x, y){
a <- x > y
b <- x < y
out <- ifelse(a, 1, ifelse(b, -1, 0))
ifelse(is.na(out), 0, out)
}
cs(df$x, df$y)
答案 2 :(得分:1)
您的代码中有一些误解:
data.frame(...,stringsAsFactors = F)
禁用的因子类型。is.numeric
甚至为NA元素也提供True
。 is.na
会完成工作||
仅比较每个向量的第一个元素。 |
进行元素比较。现在让我们实现您想要的:
实施1 :
#set up data frame
df <- data.frame(x=c(NA, 2, 9, 7, 0, 5), y=c(4, 1, 5, 9, 0, NA))
calcSignal <- function(f,s){
if(is.na(f) | is.na(s))
return(0)
else if(f>s)
return(1)
else if(f<s)
return(-1)
else
return(0)
}
df$z = mapply(calcSignal, df$x, df$y, SIMPLIFY = T)
要对两个或多个向量逐个元素运行一个函数,我们可以使用mapply
。
实施2
与以前没有太大的不同。这里的功能更易于使用。
#set up data frame
df <- data.frame(x=c(NA, 2, 9, 7, 0, 5), y=c(4, 1, 5, 9, 0, NA))
calcSignal <- function(fVector, sVector) {
res = mapply(function(f,s){
if(is.na(f) | is.na(s))
return(0)
else if(f>s)
return(1)
else if(f<s)
return(-1)
else
return(0)
},fVector,sVector,SIMPLIFY = T)
return(res)
}
df$z = calcSignal(df$x,df$y)
实施3(矢量化)
这个好多了。因为它是矢量化的,并且速度更快:
calcSignal <- function(fVector, sVector) {
res = rep(0,length(fVector))
res[fVector>sVector] = 1
res[fVector<sVector] = -1
#This line isn't necessary.It's just for clarification
res[(is.na(fVector) | is.na(sVector))] = 0
return(res)
}
df$z = calcSignal(df$x,df$y)
输出:
> df
x y z
1 NA 4 0
2 2 1 1
3 9 5 1
4 7 9 -1
5 0 0 0
6 5 NA 0