R dplyr:将列表输出写入数据框
R dplyr:将列表输出写入数据框
假设我有以下函数:
SlowFunction = function(vector){ return(list( mean =mean(vector), sd = sd(vector) )) }
我想使用dplyr:summarise将结果写入数据框:
iris %>% dplyr::group_by(Species) %>% dplyr::summarise( mean = SlowFunction(Sepal.Length)$mean, sd = SlowFunction(Sepal.Length)$sd )
有人有什么建议,我如何通过一次调用"SlowFunction"来实现这个目标,而不是两次?(在我的代码中,"SlowFunction"是一个我必须多次调用的慢函数。)当然,不能将"SlowFunction"分成两个部分。所以实际上我希望以某种方式一次性填充数据框的多列。
R dplyr中的问题是如何将列表输出写入数据框中。下面给出了两种解决方法。
第一种方法是使用`do`函数,不需要改变当前的`SlowFunction`函数。代码如下:
library(dplyr) iris %>% group_by(Species) %>% do(data.frame(SlowFunction(.$Sepal.Length)))
这段代码将iris数据集按照Species进行分组,然后对每个组应用`SlowFunction`函数,并将结果输出为数据框。输出的数据框包括Species列以及`SlowFunction`函数的计算结果。
第二种方法是使用`group_split`函数和`map_dfr`函数。代码如下:
bind_cols(Species = unique(iris$Species), iris %>% group_split(Species) %>% map_dfr(~SlowFunction(.$Sepal.Length)))
这段代码首先通过`group_split`函数将iris数据集按照Species进行分组,然后使用`map_dfr`函数对每个组应用`SlowFunction`函数,并将结果按列合并。最后,通过`bind_cols`函数将Species列与计算结果合并为一个数据框。
这两种方法都可以将列表输出写入数据框中,具体选择哪种方法可以根据实际情况和个人喜好来决定。
在上面的代码中,使用了SlowFunction
函数来计算每个Species
组中Sepal.Length
列的均值和标准差。然后,将其存储在一个list
列中,并将结果展开成一个新的data.frame
。
问题的出现原因是,如果直接将SlowFunction
的输出结果存储在一个data.frame
中,会导致计算速度非常慢。因此,使用list
列来存储输出结果可以提高计算速度。
解决方法是使用dplyr
包中的summarise
函数将输出结果存储在一个list
列中。然后,使用unnest
函数将list
列展开成一个新的data.frame
。
通过对比不同方法的计算速度,发现这种方法是最快的。相比使用do
和group_map
方法,这种方法的计算速度分别快了2倍和2.5倍。
因此,将SlowFunction
的输出结果存储在一个list
列中,并使用unnest
函数展开成一个新的data.frame
是解决这个问题的最佳方法。
R语言中的dplyr包是一个数据处理包,可以方便地对数据进行操作和转换。在使用dplyr包的过程中,有时候会遇到将列表输出转换为数据框的问题,本文就是为了解决这个问题而展开的。
在dplyr 0.8.0或更高版本中,可以使用group_map函数来解决这个问题。group_map函数可以按组逐个应用函数,并将结果转换为数据框。
以一个示例为例,我们可以使用group_by函数按照鸢尾花的种类对数据进行分组,然后使用group_map函数将SlowFunction函数应用于每个组。SlowFunction函数的输出需要被转换为数据框。
代码如下:
library(dplyr) iris %>% group_by(Species) %>% group_map(~SlowFunction(.x$Sepal.Length) %>% as.data.frame())
运行上述代码后,会得到一个数据框作为输出。数据框的列包括Species(鸢尾花的种类)、mean(Sepal.Length的均值)和sd(Sepal.Length的标准差)。数据框的行数与不同种类的鸢尾花数量相同。
通过以上的解释,我们可以清楚地了解到在使用dplyr包进行数据处理时,如果需要将列表输出转换为数据框,可以使用group_map函数来实现。这个问题的解决方法非常简单明了,只需要在group_map函数中将列表输出转换为数据框即可。