2016-07-22 65 views
0

我有一個函數我一直試圖從if(){}ifelse()。當函數的所有參數都包含在正在處理的數據集中時,它會正常工作,但如果我將參數作爲字符串提供,則向量化將停止,並且第一個結果將用於整個數據集。使用提供的變量向量化函數

下面是一個例子

# data 
dat <- data.frame(var1 = rep(c(0,1), 4), 
        var2 = c(rep("a", 4), rep("b", 4)) 
       ) 

# function 
my_fun <- function(x, y){ 
    z <- ifelse(y == "a", fun_a(x), fun_b(x)) 
    return(z) 
} 

fun_a <- function(x){ 
    z <- ifelse(x == 0, "zero", x) 
    return(z) 
} 

fun_b <- function(x){ 
    z <- ifelse(x == 1, "ONE", x) 
    return(z) 
} 
dat$var3 <- my_fun(dat$var1, dat$var2) 

這將返回我的期望,與逐行值向量根據VAR1和VAR2

> dat 
    var1 var2 var3 
1 0 a zero 
2 1 a 1 
3 0 a zero 
4 1 a 1 
5 0 b 0 
6 1 b ONE 
7 0 b 0 
8 1 b ONE 

不過,我想用不同的這個功能數據集var2不包括在內。我意識到一個簡單的方法是在數據集中添加var2作爲額外的列,但我並不想那麼做。

這是當我提供VAR2爲一個字符串會發生什麼:

other_dat <- data.frame(var1 = rep(c(0,1), 4)) 
other_dat$var3 <- my_fun(other_dat$var1, y = "a") 
other_dat 
    var1 var3 
1 0 zero 
2 1 zero 
3 0 zero 
4 1 zero 
5 0 zero 
6 1 zero 
7 0 zero 
8 1 zero 

我怎樣才能vectorise這個功能,所以它接受一個字符串參數,並返回我想要的結果呢?

回答

1

可以矢量化y,即將y的長度與x的長度相似,然後ifelse將在所有值上應用函數my_func。修改後的代碼:

# data 
dat <- data.frame(var1 = rep(c(0,1), 4), 
        var2 = c(rep("a", 4), rep("b", 4)) 
       ) 

# function 
my_fun <- function(x, y){ 
    if(length(y) == 1) { 
    y <- rep(y, length(x)) 
    } 
    z <- ifelse(y == "a", fun_a(x), fun_b(x)) 
    return(z) 
} 

fun_a <- function(x){ 
    z <- ifelse(x == 0, "zero", x) 
    return(z) 
} 

fun_b <- function(x){ 
    z <- ifelse(x == 1, "ONE", x) 
    return(z) 
} 
dat$var3 <- my_fun(dat$var1, "a") 

other_dat <- data.frame(var1 = rep(c(0,1), 4)) 
other_dat$var3 <- my_fun(other_dat$var1, y = "a") 
other_dat 

希望這會有所幫助。

+0

更新了代碼。 –

+0

完美,非常感謝。這是我忽略的一個很好的解決方案。 –