【问题标题】:Using anonymous functions with lapply/sapply in R?在 R 中使用带有 lapply/sapply 的匿名函数?
【发布时间】:2019-01-11 18:01:04
【问题描述】:

我正在尝试使用 sapply 获取列表中的每个项目(例如“Golf”、“Malibu”、“Corvette”),并创建一个新列表,该列表在拆分列表的数据框中具有最高值(例如汽车$sale_price)。我正在尝试使用匿名函数来执行此操作,但我无法使该函数正常工作。

这里的基本问题是我不太擅长编写函数。

首先,我获取原始数据框 cars 并使用 split 创建一个唯一汽车名称列表 - 我将其命名为 car_names

现在,我正在尝试使用 sapply 创建一个新列表,列出列表中每种汽车的最高售价。我确定我正确地开始了这件事......

price_list <- sapply(car_names, 

...但是我一辈子都无法获得一个匿名函数来简单地将max 应用于汽车售价中每个汽车名称的所有实例。

我尝试了很多东西,所有这些都返回了错误。这是一个例子:

price_list <- sapply(car_names, function(x) {
    max(cars$saleprice[x])
})

返回:

Error in h115$nominate_dim1[x] : invalid subscript type 'list'

我敢肯定,即使对于经验中等的程序员来说,这也是微不足道的,但我……不是其中之一!我怀疑我指向错误的东西,但我无法超越它。有什么想法吗?


编辑:这是一个可重现的示例。

首先,“源”数据框:

cars1 <- data.frame("car_names" = c("Corvette", "Corvette", "Corvette", "Golf", "Golf", "Golf", "Malibu", "Malibu", "Malibu"),"saleprice" = c(32000,45000,72000,7500,16000,22000,33000,21000,26500))

接下来,按汽车名称拆分 df:

cars1_split <- split(cars1, cars1$car_names)

现在,尝试将 max 传递给 sapply 并收到错误:

maxes <- sapply(cars1_split, function(x){
  max(cars1$saleprice[x])
})

希望这能给你们一些工作!

【问题讨论】:

  • 我认为问题在于“car_names”中的每个元素都是一个列表。如果 x 是一个列表, max(cars$saleprice[x]) 将导致错误。我认为这就是您收到错误的原因,但除非您发布可重现的示例,否则无法确定。
  • 您应该分享reproducible example 并显示预期的输出。
  • 你们是对的,@markus 和@David-Rosenman!感谢您的反馈。我有一两个小时很忙,但很快会分享一个简单的可重现示例。

标签: r lapply anonymous-function sapply


【解决方案1】:

你有几个选择,让我们从aggregate开始 - 不是你要求的,但我想保持你的高度关注;)

aggregate(saleprice ~ car_names, cars1, max)
#  car_names saleprice
#1  Corvette     72000
#2      Golf     22000
#3    Malibu     33000

返回一个data.frame(如果你需要一个列表,你可以很容易地split

aggregate 类似于 tapply 下一个

tapply(cars1$saleprice, cars1$car_names, FUN = max)
#Corvette     Golf   Malibu 
#   72000    22000    33000

或者试试bywhich.max

by(cars1, cars1$car_names, FUN = function(x) x[which.max(x$saleprice), ])
#cars1$car_names: Corvette
#  car_names saleprice
#3  Corvette     72000
#-------------------------------
#cars1$car_names: Golf
#  car_names saleprice
#6      Golf     22000
#-------------------------------
#cars1$car_names: Malibu
#  car_names saleprice
#7    Malibu     33000

最后,您还可以使用lapplysplitby 有点简写)

lapply(split(cars1, cars1$car_names), function(x) x[which.max(x$saleprice), ])
#$Corvette
#  car_names saleprice
#3  Corvette     72000

#$Golf
#  car_names saleprice
#6      Golf     22000

#$Malibu
#  car_names saleprice
#7    Malibu     33000

【讨论】:

  • 伙计,这太棒了。 aggregate 干净多了!
  • 跟进:如果我想做 lapply ,就像你上一个例子一样,但现在我想计算平均销售价格而不是最高价格,我该怎么做?据我所知,没有which.mean,用mean替换which.max会给我一个混乱的矩阵。
  • @logjammin 抱歉耽搁了,您需要lapply(split(cars1, cars1$car_names), function(x) mean(x$saleprice))。但是你最好在这里使用aggregate
猜你喜欢
  • 2021-08-05
  • 2012-10-15
  • 2020-10-14
  • 2023-03-06
  • 2015-02-20
  • 1970-01-01
  • 1970-01-01
  • 2020-07-01
  • 2021-02-05
相关资源
最近更新 更多