2017-06-13 161 views
2

我創建了一個函數,根據一個id減去我的一些數據。該功能正常工作,直到dplyr更新。最初該函數不接受列名作爲函數中的輸入。我使用Programming with dplyr來調整函數以接受列名,但是現在我得到一條新的錯誤消息。dplyr:函數錯誤信息

testdf <- structure(list(date = c("2016-04-04", "2016-04-04", "2016-04-04", 
         "2016-04-04", "2016-04-04", "2016-04-04"), sensorheight = c(1L, 
                        16L, 1L, 16L, 1L, 16L), farm = c("McDonald", "McDonald", 
                                "McDonald", "McDonald", "McDonald", "McDonald" 
                        ), location = c("4", "4", "5", "5", "Outside", "Outside"), Temp = c(122.8875, 
                                         117.225, 102.0375, 98.3625, 88.5125, 94.7)), .Names = c("date", 
                                                       "sensorheight", "farm", "location", "Temp"), row.names = c(NA, 
                                                                      6L), class = "data.frame") 


DailyInOutDiff <- function (df, variable) { 

    DailyInOutDiff04 <- df %>% 
    filter(location %in% c(4, 'Outside')) %>% 
    group_by(date, sensorheight, farm) %>% 
    arrange(sensorheight, farm, location) %>% 
    summarise(Diff = if(n()==1) NA else !!variable[location=="4"] - !!variable[location=='Outside'], 
       location = "4") %>% 
    select(1, 2, 3, 5, 4) 

    DailyInOutDiff05 <- df %>% 
    filter(location %in% c(5, 'Outside')) %>% 
    group_by(date, sensorheight, farm) %>% 
    arrange(sensorheight, farm, location) %>% 
    summarise(Diff = if(n()==1) NA else !!variable[location=="5"] - !!variable[location=='Outside'], 
       location = "5") %>% 
    select(1, 2, 3, 5, 4) 

    temp.list <- list(DailyInOutDiff04, DailyInOutDiff05) 
    final.df = bind_rows(temp.list) 
    return(final.df) 
} 

test <- DailyInOutDiff(testdf, quo(Temp)) 

我想知道錯誤信息的含義以及如何解決它。

Error in location == "4" : 
    comparison (1) is possible only for atomic and list types 

回答

2

我認爲!的優先級是導致問題。當發生這種情況時,應該使用UQ來代替!!

在這種情況下,你的函數的第一部分看起來像

DailyInOutDiff <- function (df, variable) { 

    variable = enquo(variable) 

    df %>% 
     filter(location %in% c(4, 'Outside')) %>% 
     group_by(date, sensorheight, farm) %>% 
     arrange(sensorheight, farm, location) %>% 
     summarise(Diff = if(n()==1) NA else UQ(variable)[location == "4"] - 
        UQ(variable)[location == "Outside"], 
       location = "4") 

} 

這就是現在運行沒有錯誤。

DailyInOutDiff(testdf, Temp) 

     date sensorheight  farm Diff location 
     <chr>  <int> <chr> <dbl> <chr> 
1 2016-04-04   1 McDonald 34.375  4 
2 2016-04-04   16 McDonald 22.525  4 

我認爲使用UQ可能是最好的方法。另一種選擇是以功能的形式使用提取括號。這也繞過了優先問題。

例如,代碼看起來像

!!variable[location == "4"] 

可以作爲

`[`(!!variable, location == "4") 

進行這些改變你的函數的第一部分被改寫,事情看起來像

DailyInOutDiff <- function (df, variable) { 

    variable = enquo(variable) 

    df %>% 
     filter(location %in% c(4, 'Outside')) %>% 
     group_by(date, sensorheight, farm) %>% 
     arrange(sensorheight, farm, location) %>% 
     summarise(Diff = if(n()==1) NA else `[`(!!variable, location == "4") - 
        `[`(!!variable, location == "Outside"), 
       location = "4") 

} 

其中也沒有錯誤地運行

DailyInOutDiff(testdf, Temp) 

     date sensorheight  farm Diff location 
     <chr>  <int> <chr> <dbl> <chr> 
1 2016-04-04   1 McDonald 34.375  4 
2 2016-04-04   16 McDonald 22.525  4 
+0

'UQ'很棒,我喜歡在功能中包含'enquo'。謝謝。 – phaser