首页 > 解决方案 > R,对多个元素应用函数

问题描述

我的函数定义如下,其中我将数据框子集为特定名称并返回前 5 个元素。

Bestideas <- function(x) {
  topideas <- subset(Masterall, Masterall$NAME == x) %>%
  slice(1:5)
  return(topideas)

然后,我想将该函数应用于整个 df(具有一列名称),以便将该函数应用于列表中的每个名称并将其绑定到一个新的 df 中,其中包含来自所有唯一名称的前五个想法. 通过研究-我得出以下结论:

bestideas_collection = lapply(UNIQUE_NAMES_DF, Bestideas) %>% bind_rows()

但是,它不起作用。它返回一个数据框,总共只有五个想法,来自 5 个不同的名称。由于我的列表中有 30 个唯一名称,我预计“bestideas_collection”变量中有 30*5 = 150 个想法。我收到此错误消息:

“较长的对象长度不是较短对象长度的倍数较长的对象长度不是较短对象长度的倍数”

此外,如果我为每个名称手动执行此操作,它会按预期工作 - 这让我认为该功能工作正常,而问题在于 lapply 功能。

holder <- Bestideas("NAME 1")
bestideas_collection <- bind_rows(bestideas_collection,holder)

holder <- Bestideas("NAME 2")
bestideas_collection <- bind_rows(bestideas_collection,holder)

holder <- Bestideas("NAME 3")
bestideas_collection <- bind_rows(bestideas_collection,holder)

...

如果我使用错误的功能,谁能帮助我,或者你有其他方法吗?我已经尝试过使用 for 循环 - 但它给了我与 lapply 函数相同的错误。

标签: r

解决方案


我没有你的数据,所以我试图在一个虚构的集合上重现你的问题。我无法这样做。通过一个非常简单的案例,您的函数可以按预期工作。

library(dplyr)
set.seed(123)
Masterall <- data.frame(NAME = rep(LETTERS, 10), value = rnorm(260)) %>% 
  group_by(NAME) %>% arrange(desc(value))
UNIQUE_NAMES_DF <- LETTERS

lapply(UNIQUE_NAMES_DF, Bestideas) %>% bind_rows()
# A tibble: 130 x 2
# Groups:   NAME [26]
   NAME    value
   <chr>   <dbl>
 1 A      1.65  
 2 A      1.44  
 3 A      0.838 
 4 A      0.563 
 5 A      0.181 
 6 B      1.37  
 7 B      0.452 
 8 B      0.153 
 9 B     -0.0450
10 B     -0.0540
# ... with 120 more rows

你是UNIQUE_NAMES_DF一个data.frame吗?如果是这样,那就麻烦了。该lapply函数需要一个向量作为它的第一个输入。它可以处理 data.frame,但显然会出现意想不到的结果。这是一个例子:

UNIQUE_NAMES_DF <- data.frame(NAME = LETTERS, other = sample(letters))
lapply(UNIQUE_NAMES_DF, Bestideas) %>% bind_rows()

# A tibble: 12 x 2
# Groups:   NAME [11]
   NAME    value
   <chr>   <dbl>
 1 C     -0.785 
 2 D      0.385 
 3 E     -0.371 
 4 F      1.13  
 5 I      1.10  
 6 N     -0.641 
 7 P     -1.02  
 8 Q     -0.0341
 9 U     -1.07  
10 X     -0.0834
11 Z      1.26  
12 Z     -0.739 

我不知道您的结构UNIQUE_NAMES_DF,但是如果您只是将带有名称的列输入到您的lapply中,它应该可以工作:

lapply(UNIQUE_NAMES_DF$NAME, Bestideas) %>% bind_rows()
# A tibble: 130 x 2
# Groups:   NAME [26]
   NAME    value
   <chr>   <dbl>
 1 A      1.65  
 2 A      1.44  
 3 A      0.838 
 4 A      0.563 
 5 A      0.181 
 6 B      1.37  
 7 B      0.452 
 8 B      0.153 
 9 B     -0.0450
10 B     -0.0540
# ... with 120 more rows

推荐阅读