【问题标题】:Ignoring NA values in function忽略函数中的 NA 值
【发布时间】:2018-04-24 19:16:29
【问题描述】:

我正在编写自己的函数来计算数据集中列的平均值,然后使用apply() 应用它,但它只返回第一列的平均值。以下是我的代码:

mymean <- function(cleaned_us){
  column_total = sum(cleaned_us)
  column_length = length(cleaned_us)
  return (column_total/column_length)
}

Average_2 <- apply(numeric_clean_usnews,2,mymean,na.rm=T)

【问题讨论】:

  • sum 还有na.rm 参数sum(cleaned_us, na.rm = TRUE) 另外,你可以使用colMeans(numeric_clean_usnews, na.rm = TRUE)
  • 完美,可行,但我认为它可能会占用元素总数的长度并且不排除 NA。我尝试了 na.rm 的长度,但它没有使用它。我也希望我可以使用 colMeans,但它要求我们自己制作
  • 我没有注意到长度。你可以使用sum(!is.na(cleaned_us))

标签: r function na


【解决方案1】:

我们需要在sum 中使用na.rm=TRUE,而在apply 中使用它是行不通的,因为mymean 没有那个参数

mymean <- function(cleaned_us){
   column_total = sum(cleaned_us, na.rm = TRUE) #change
   column_length = sum(!is.na(cleaned_us)) #change
  return(column_total/column_length)
 }

请注意,colMeans 可用于获取每列的mean

【讨论】:

  • 这对我有用,但我们为什么要 sum(!is.na(cleaned_us)) 长度?只是好奇!
  • @J.McCraiton !is.na(cleaned_us) 为非 NA/NA 元素提供 TRUE/FALSE 的逻辑向量,sum 将获得这些非 NA 的总和,即sum(!is.na(c(NA, 3, 5, NA)))#[1] 2。但是,length 将在此处给出 4。我想这就是你想要的,对,或者你可以做length(cleaned_us[!is.na(cleaned_us)]),但与sum相比它会慢一些
【解决方案2】:

为了将na.rm 参数传递给您定义的函数,您需要将其作为函数的参数。 sum() 函数有一个 na.rm 参数,但 length() 没有。因此,要编写您尝试编写的函数,您可以说:

# include `na.rm` as a param of the argument 
mymean <- function(cleaned_us, na.rm){

  # pass it to `sum()` 
  column_total = sum(cleaned_us, na.rm=na.rm)

  # if `na.rm` is set to `TRUE`, then don't count `NA`s 
  if (na.rm==TRUE){
    column_length = length(cleaned_us[!is.na(cleaned_us)])

  # but if it's `FALSE`, just use the full length
  } else {
    column_length = length(cleaned_us)
  }

  return (column_total/column_length)
}

那么你的电话应该可以工作了:

Average_2 <- apply(numeric_clean_usnews, 2, mymean, na.rm=TRUE)

【讨论】:

  • 我认为 if 语句是多余的。也许在函数定义中将na.rm 设置为false。
  • 这个定义是为了说明的目的,所以在现实世界的场景中它确实会更紧凑。不确定我是否看到“冗余”
【解决方案3】:

使用na.omit()

set.seed(1)
m <- matrix(sample(c(1:9, NA), 100, replace=TRUE), 10)

mymean <- function(cleaned_us, na.rm){
    if (na.rm) cleaned_us <- na.omit(cleaned_us)
    column_total = sum(cleaned_us)
    column_length = length(cleaned_us)
    column_total/column_length
}

apply(m, 2, mymean, na.rm=TRUE)

# [1] 5.000 5.444 4.111 5.700 6.500 4.600 5.000 6.222 4.700 6.200

【讨论】:

    猜你喜欢
    • 2012-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2012-03-19
    • 2013-03-26
    相关资源
    最近更新 更多