2017-08-31 21 views
0

考慮這個簡單的例子如何用lm來使用?

library(dplyr) 
library(broom) 

dataframe <- data_frame(id = c(1,2,3,4,5,6), 
         value = c(NA,NA,NA,NA,NA,NA)) 
dataframe 

> dataframe 
# A tibble: 6 x 2 
    id value 
    <dbl> <lgl> 
1  1 NA 
2  2 NA 
3  3 NA 
4  4 NA 
5  5 NA 
6  6 NA 

我基本上使用lm計算列的平均值在我的數據幀的功能。

get_mean <- function(data, myvar){ 
    col_name <- as.character(substitute(myvar)) 
    fmla <- as.formula(paste(col_name, "~ 1")) 
    tidy(lm(data = data, fmla, na.action = 'na.omit')) %>% pull(estimate) 
} 

現在

> get_mean(dataframe, id) 
[1] 3.5 

因爲缺失值,但是,

get_mean(dataframe, value) 

返回到返回NA或任意數量的可怕

Error in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) : 
    0 (non-NA) cases 

我想功能由我指定w如果出現全NA情況。我試圖用purrr:possibly但沒有成功

get_mean <- function(data, myvar){ 
    col_name <- as.character(substitute(myvar)) 
    fmla <- as.formula(paste(col_name, "~ 1")) 
    model <- purrr::possibly(lm(data = data, fmla, na.action = 'na.omit'), NA) 
    if(!is.na(model)) { 
    tidy(model) %>% pull(estimate) 
    } 
} 

get_mean(dataframe, id) 

不起作用

Error: Can't convert a list to function

我該怎麼辦? 謝謝!

+1

您確定要使用'可能是()'這裏?這是一個函數,它接受一個函數並返回另一個函數 - 這些函數都不是你真正想要的。 – MrFlick

+0

啊!那時我很困惑。我也嘗試過'tryCatch',但沒有成功。我很好,你看到了你的方式。謝謝! –

+3

使用'tryCatch'。像'return(tryCatch(<你的lm代碼>,error = function(e)NA))'''。 – Gregor

回答

5

您可以將整個函數包裝在possibly中,因此如果整個函數在任何地方失敗,您都可以獲得NA。

get_mean <- possibly(function(data, myvar) { 
    col_name <- as.character(substitute(myvar)) 
    fmla <- as.formula(paste(col_name, "~ 1")) 
    model <- lm(data = data, fmla, na.action = 'na.omit') 
    tidy(model) %>% pull(estimate) 
}, otherwise = NA) 

get_mean(dataframe, id) 
[1] 3.5 
get_mean(dataframe, value) 
[1] NA 

然而,不同於tryCatch這不是專注於代碼的lm一部分。它正在處理整個功能,如果因任何原因發生任何錯誤,它將返回NA。例如,如果您在運行get_mean之前忘記加載掃帚包,即使模型正常工作,您也會收到NA,因爲R無法找到tidy

將參數quiet設置爲FALSE將允許打印錯誤消息,這可以幫助您減輕像上面概述的錯誤。

您也可以使用possibly作爲safely的文檔示例,使possibly函數專用於lm以供使用。然後,您可以使用if else語句或者tidy或返回NA

get_mean <- function(data, myvar) { 
    col_name <- as.character(substitute(myvar)) 
    fmla <- as.formula(paste(col_name, "~ 1")) 
    poss_lm <- possibly(lm, otherwise = NA) 
    model <- poss_lm(data = data, fmla, na.action = 'na.omit') 
    if(!is.na(model[1])) { 
      tidy(model) %>% pull(estimate) 
    } 
    else { 
      model 
    } 
} 
+0

的好聽,甚至可能更好。失敗證明:D –

+1

失敗證明意味着難以檢測和診斷問題,難以修復。 aosmith給出了一個很好的例子,如果不知道'掃帚'是不是加載,而不是信息性的錯誤信息,你只是得到所有'NA'結果... – Gregor

3

看起來像一個普通的tryCatch()會做的伎倆

get_mean <- function(data, myvar){ 
    col_name <- as.character(substitute(myvar)) 
    fmla <- as.formula(paste(col_name, "~ 1")) 
    tryCatch(lm(data = data, fmla, na.action = 'na.omit') %>% tidy() %>% pull(estimate), 
        error=function(e) NA) 
} 
get_mean(dataframe, id) 
# [1] 3.5 
get_mean(dataframe, value) 
# [1] NA 
+0

感謝您的替代解決方案! –