2016-10-24 30 views
0

我的數據是這樣的:意外的值,而在dplyr應用自定義功能::變異

library(tidyverse) 

df <- tribble(
    ~y_val, ~z_val, 
    2, 4, 
    5, 3, 
    8, 2, 
    1, 1, 
    9, 3) 

我有自定義函數fun_b(),我想申請到了dplyr ::發生變異的呼叫數據幀。然而,fun_b()使用功能fun_a()它有它內部的一個循環:

fun_a <- function(x, y, z, times = 1) { 

    df <- data.frame() 
    for (i in 1:times) { 
     x <- x * 2 + i * x 
     y <- y/3 + i * y 
     z <- z + 1 + z * i 
    d <- data.frame(x, y, z) 
    df <- rbind(df, d) 
    } 
    return(df) 
} 

fun_b <- function(x, y, z, times = 1) { 
    df <- fun_a(x, y, z, times) 
    x_r <- sum(df$x) 
    y_r <- sum(df$y) 
    z_r <- sum(df$z) 
    val <- x_r/y_r * z_r 
    return(val) 
} 

當我運行自定義功能:

df %>% 
    mutate(test = fun_b(x = 1, y = y_val, z = z_val, times = 1)) 

test每個突變值顯示相同的值(13.95)。這沒有道理!例如,蹣跚(y_val = 2, z_val = 4)的第一行應該是10.125!

fun_b(x = 1, y = 2, z = 4, times = 1) 

這是怎麼回事?

+0

你只需要組或者只是取出'sum'調用,這樣你的行爲就會變成行,即'df%>%rowwise()%>% mutate(test = fun_b(x = 1,y = y_val,z = z_val,times = 1)功能是可以矢量化的 – alistaire

回答

1

您可以將橫行等等功能得到每一行分別進行評估:

df %>% 
    rowwise() %>% 
    mutate(test = fun_b(x = 1, y = y_val, z = z_val, times = 1)) 

## Source: local data frame [5 x 3] 
## Groups: <by row> 
## 
## # A tibble: 5 × 3 
## y_val z_val  test 
## <dbl> <dbl> <dbl> 
## 1  2  4 10.12500 
## 2  5  3 3.15000 
## 3  8  2 1.40625 
## 4  1  1 6.75000 
## 5  9  3 1.75000 

或編輯fun_b得到所以它的矢量,或只是讓R:

df %>% mutate(test = Vectorize(fun_b)(x = 1, y = y_val, z = z_val, times = 1)) 

## # A tibble: 5 × 3 
## y_val z_val  test 
## <dbl> <dbl> <dbl> 
## 1  2  4 10.12500 
## 2  5  3 3.15000 
## 3  8  2 1.40625 
## 4  1  1 6.75000 
## 5  9  3 1.75000 
1

請嘗試以下

df %>% 
    group_by(y_val, z_val) %>% 
    mutate(test = fun_b(x = 1, y = y_val, z = z_val, times = 1)) 

這讓我10.125。