如何用purrr的map函数计算矩阵列的峰度?NaN报错求解
解决用purrr计算矩阵列峰度返回NaN的问题
我使用datasets::volcano作为数据集,用base R的apply可以顺利计算每列的峰度(指定e1071::kurtosis的type=2)和sd(x)/mad(x)指标,并生成新数据框:
install.packages('e1071') library(e1071) library(tidyverse) mydata <- datasets::volcano head(mydata) # Part 1: base R实现 kurtosis <- apply(mydata, 2, function(x) kurtosis(x, type = 2)) new_measure <- apply(mydata, 2, function(x) sd(x) / mad(x)) base_mydata <- data.frame(kurtosis = kurtosis, new_measure = new_measure)
但改用purrr的map_dbl计算每列峰度时,得到的全是NaN值,代码如下:
# Part 2: 出现问题的purrr代码 kurtosis_value <- mydata %>% map_dbl(~ kurtosis(.x))
问题原因
volcano是矩阵类型,purrr的map系列函数默认会将矩阵视为一维向量,逐个迭代每个元素而非按列迭代。单个数值无法计算峰度,因此返回NaN;同时代码中未指定type=2参数,和Part1的计算逻辑不一致。
修正后的代码
1. 仅计算每列峰度
先将矩阵转为数据框(purrr对数据框默认按列迭代),同时加上type=2参数:
kurtosis_value <- mydata %>% as.data.frame() %>% map_dbl(~ kurtosis(.x, type = 2))
2. 完整复刻Part1的逻辑,生成包含两个指标的数据框
用dplyr实现:
dplyr_mydata <- mydata %>% as.data.frame() %>% summarize( across(everything(), list( kurtosis = ~ kurtosis(.x, type = 2), new_measure = ~ sd(.x) / mad(.x) )) ) %>% tidyr::pivot_longer( cols = everything(), names_to = c("column", ".value"), names_sep = "_" )
用purrr实现:
purrr_mydata <- mydata %>% as.data.frame() %>% purrr::map_dfr( ~ tibble( kurtosis = kurtosis(.x, type = 2), new_measure = sd(.x) / mad(.x) ), .id = "column" )
内容的提问来源于stack exchange,提问作者Ian Kelly
相关产品推荐
相关产品推荐

