sapply输出异常:无法将矩阵转换为目标DataFrame的技术问询
解决sapply调用Vasicek函数后转换为3列DataFrame的问题
问题背景
我编写了一个返回3列DataFrame的Vasicek函数,单独调用(如Vasicek(1))时输出格式符合预期:
Vasicek(1) Data DU Yield 1 2019-01-02 0.06027397 0.06428780 2 2019-01-02 0.16712329 0.06334294 3 2019-01-02 0.33698630 0.06336400 4 2019-01-02 0.69315068 0.06531485 5 2019-01-02 1.03013699 0.06833951 6 2019-01-02 1.38082192 0.07188101 7 2019-01-02 2.06849315 0.07848185 8 2019-01-02 2.75616438 0.08374200 9 2019-01-02 4.13424658 0.09019618 10 2019-01-02 5.51232877 0.09296135
但使用sapply(1:3, Vasicek)调用后,返回对象类型为matrix/array:
class(Vas) [1] "matrix" "array" Vas = sapply(1:3, Vasicek) Vas [,1] [,2] [,3] Data Numeric,5 Numeric,5 Numeric,5 DU Numeric,5 Numeric,5 Numeric,5 Yield Numeric,5 Numeric,5 Numeric,5
该对象的结构如下:
structure(list(structure(c(17898, 17898, 17898, 17898, 17898), class = "Date"), c(1.38082191780822, 4.13424657534247, 0.167123287671233, 1.03013698630137, 2.06849315068493), c(0.0718810119824251, 0.0901961821101735, 0.0633429401279062, 0.0683395111286434, 0.0784818512451727), structure(c(17899, 17899, 17899, 17899, 17899), class = "Date"), c(2.06575342465753, 0.164383561643836, 0.0575342465753425, 2.75342465753425, 0.334246575342466), c(0.0787273534815518, 0.063925820453163, 0.0641495440691283, 0.084047539923232, 0.0639744930251083), structure(c(17900, 17900, 17900, 17900, 17900), class = "Date"), c(2.75068493150685, 1.37534246575342, 1.02465753424658, 1.71232876712329, 0.161643835616438 ), c(0.0820164309541394, 0.0726562058606185, 0.0700359442531045, 0.075140202621196, 0.0636353259162377)), .Dim = c(3L, 3L), .Dimnames = list( c("Data", "DU", "Yield"), NULL))
需要将该matrix/array转换为与单独调用函数一致的3列DataFrame。
解决方案
方法1:替换sapply为lapply后合并
sapply会自动简化结果结构,改用lapply保留每个调用返回的DataFrame列表,再合并为一个大DataFrame:
# 生成DataFrame列表 vas_list <- lapply(1:3, Vasicek) # 合并所有DataFrame result_df <- do.call(rbind, vas_list) # 或者用dplyr包的bind_rows更直观 library(dplyr) result_df <- bind_rows(vas_list)
方法2:从已有的matrix/array转换
如果已经得到了sapply返回的matrix对象,可以遍历每一列,将Data、DU、Yield向量组合为DataFrame后再合并:
# 遍历matrix的每一列,生成单个DataFrame vas_dfs <- lapply(1:ncol(Vas), function(i) { data.frame( Data = Vas["Data", i], DU = Vas["DU", i], Yield = Vas["Yield", i] ) }) # 合并所有DataFrame result_df <- do.call(rbind, vas_dfs)
方法3:使用purrr包的map_dfr直接生成DataFrame
purrr包的map_dfr函数可以直接将函数应用到向量上,并自动合并结果为DataFrame:
library(purrr) result_df <- map_dfr(1:3, Vasicek)
说明
sapply之所以会返回matrix/array,是因为它尝试将每个DataFrame拆分为列向量,再将这些向量整理为矩阵结构,导致每个单元格存储的是一个向量而非单个值。而lapply或map_dfr会保留每个调用返回的完整DataFrame,从而可以直接合并为目标格式。
内容的提问来源于stack exchange,提问作者Osvaldo Assunção
相关产品推荐
相关产品推荐

