将NA放入列表中

时间:2017-09-01 13:32:29

标签: r list na

经过多次尝试和失败后,我带来了以下数据:

canada <- c(100, 80, 100, 100, 20)
korea <- c(100, "", 100, "", "")
brazil <- c(100, 90, 100, 30, 30)
fruit <- rbind(canada, korea, brazil)
colnames(fruit) <- c("apple", "orange", "banana", "grape", "kiwi")
fruit

我希望它看起来像这样:

> price("korea")
Thank you, StackOverflow, for the delicious apple and banana.

所以我尝试了以下内容:

price <- function(val){
  val <- tolower(val)
  myrow <- fruit[val,]
  nation <- tools::toTitleCase(val)

  name.min <- names(myrow)[which.min(c(myrow))]
  name.max <- sapply(seq_along(myrow), 
                     function(x, n, i) {paste0(n[i])},
                     x=myrow, n=names(na.omit(which(myrow == max(myrow)))))
  name.max[length(name.max)] <- paste0("and ", name.max[na.omit(length(name.max))])
  name.max <- paste(name.max, collapse = ", ")

  cat(paste0("My fruits have a NAsty taste at the end: ", name.max))
} 

其中印有以下内容:

> price("korea")
My fruits have a NAsty taste at the end: apple, banana, NA, NA, and NA

我使用na.omit函数错了吗?

2 个答案:

答案 0 :(得分:1)

我认为你可以简单地将你的矢量myrow包装在na.omit中。

as.vector(na.omit(myrow))

例如

as.vector(na.omit(c(NA, 2,2,3)))
[1] 2 2 3

所以,如果你只想获得你的名字.min或name.max,你可以这样做。

name.min <- names(myrow)[which.min(na.omit(myrow))]
name.max <- names(myrow)[which.max(na.omit(myrow))]

这样,您可以省略sapply()调用并替换如下。

price <- function(val){
  val <- tolower(val)
  myrow <- fruit[val,]
  nation <- tools::toTitleCase(val)
  #
  if (min(myrow, na.rm = TRUE) == max(myrow, na.rm = TRUE)) {
    name.max <-  as.vector(na.omit(names(myrow)[myrow == max(myrow, na.rm = TRUE)]))
  } else {
    name.max <- names(myrow)[which.max(na.omit(myrow))]
  }
  cat(paste0("My fruits have a NAsty taste at the end: ", paste(name.max, collapse = ", ")))
} 

结果应符合预期。

# data
canada <- as.numeric(c(100, 80, 100, 100, 20))
korea <- as.numeric(c(100, "", 100, "", ""))
brazil <- as.numeric(c(100, 90, 100, 30, 30))
fruit <- rbind(canada, korea, brazil)
colnames(fruit) <- c("apple", "orange", "banana", "grape", "kiwi")

# run
price("korea")
My fruits have a NAsty taste at the end: apple, banana

答案 1 :(得分:1)

seq_along myrow,并使用它来访问n,但n的元素少于myrow,因为您删除了所有值为{1}的元素小于max(myrow)

如果更改了该值,则只会获得值等于max的那些:

price <- function(val){

  val <- tolower(val)
  myrow <- fruit[val,]
  nation <- tools::toTitleCase(val)

  name.min <- names(myrow)[which.min(c(myrow))]
  name.max <- sapply(seq_along(na.omit(which(myrow == max(myrow)))), 
                     function(x, n, i) {paste0(n[i])},
                     x=myrow, n=names(na.omit(which(myrow == max(myrow)))))
  name.max[length(name.max)] <- paste0("and ", name.max[na.omit(length(name.max))])
  name.max <- paste(name.max, collapse = ", ")

  cat(paste0("My fruits don't have a NAsty taste at the end: ", name.max))
} 

那就是说,你想要这个功能做什么有点不清楚。我确信有更优雅的方式来做到这一点。例如,为什么要计算name.min并且从不使用它?

如果您只想要值等于最大值的列名称,那么这样可读性和效率更高:

name.max <- names(myrow[myrow == max(myrow)])