2016-08-19 68 views
1

我有一個數據集,其中有460K個觀測值加載到名爲data的數據框中。一個變量的定義如下:dplyr mutate調用一個函數的結果不正確

$ exeroft1 <int> NA, 105, NA, 205, NA, 102, 220, 102, 102, 220, 230, NA, NA, 105, 102, 210, 203, NA, NA, 107, 103, NA, 203, NA, NA, 105, 107, NA, 102, NA, 107, NA, 107, 103, ... 

我需要的exeroft1每個值傳遞到下面的函數,其值轉換成另一個值:

calculateWeeklyExercise <- function(value) { 
    if (value > 200) { 
     timesWeekly = (value - 200)/4 
    } else { 
     timesWeekly = (value - 100) 
    } 

    timesWeekly 
} 

下面是一些R代碼裏面那完成所有的處理:

data %>% 
    # Filter missing values 
    filter(!is.na(exeroft1)) %>% 

    # Add a column to the data frame which represents exercise rate 
    mutate(weeklyExercise = calculateWeeklyExercise(exeroft1)) %>% 

    # Select some values 
    select(educa, sex, exeroft1, weeklyExercise) 

當我執行這個代碼,我得到以下警告,這一點我不明白:

Warning message: 
In if (value > 200) { : 
    the condition has length > 1 and only the first element will be used 

我對R不是很有經驗。看來我傳遞給函數的值並不被視爲整數,即使它是。對於任何值< 200,計算正確的值。對於任何值> 200,不是。所以,在本質上,在函數中,只有else子句似乎永遠得到執行。

+0

當你的長度大於1時,它與'if/else'問題有關。使用'ifelse'或者如果我們正在申請每一行,那麼'data%>% filter(!is .na(exeroft1))%>%rowwise()%>%>'並執行此操作。 – akrun

+0

@akrun - 雖然我不明白。爲什麼'value'被視爲長度大於1的整數? –

+0

如果我明白了(沒有一個可重複的例子),這個值是以一個列作爲輸入,並且該列的長度> 1.即'if(1:3> 2)1'得到相同的警告 – akrun

回答

2

如果我們修改函數使用ifelse即。的if/else向量化形式,其可以採取多個值,那麼它應該工作

calculateWeeklyExerciseNew <- function(value) { 
    ifelse(value > 200, 
      (value - 200)/4, 
       value - 100) 

} 

警告消息是明顯爲OP的函數應用到數據集的列中的元素的數量大於1由於if/else只需要一次觀察,就會引發警告。即

if(1:3 >2) 1 

警告消息:在如果(1:3> 2)1:條件具有長度> 1 且僅第一個元素將被用來

在上述例子中,我們有長3(1:3)的載體,它給出了警告,如果我們做與ifelse

ifelse(1:3 >2, 1, 0) 
#[1] 0 0 1 

但是假設,我們仍然可以使用在OP的功能通過執行rowwise

data %>% 
    filter(!is.na(exeroft1)) %>% 
    rowwise() %>% 
    mutate(weeklyExercise = calculateWeeklyExercise(exeroft1)) %>% 
    select(educa, sex, exeroft1, weeklyExercise) 

採取只有一個觀察,但它會慢一些。

+1

謝謝。很好的解釋。 –

+0

僅供參考,我嘗試了ifelse,但我仍然收到警告和錯誤結果。 –

+0

@RandyMinder你還沒有提供一個可重複的例子來測試它。我的建議是基於你展示的警告。 – akrun

相關問題