【问题标题】:Calculations across dataframes跨数据框的计算
【发布时间】:2019-04-10 14:12:42
【问题描述】:

我有两个数据框列表,第一个 dfs 列表保存沿列向下延伸的值,第二个 dfs 列表保存单个值,如下所示:

dynamic_df_1 <- data.frame(x = 1:10)
dynamic_df_2 <- data.frame(y = 1:10)
df_list <- list(dynamic_df_1, dynamic_df_2)
df_list

static_df_1 <- data.frame(mu = 10,
                          stdev = 5)
static_df_2 <- data.frame(mu = 12,
                          stdev = 6)
static_df_list <- list(stat_df1 = static_df_1, 
                       stat_df2 = static_df_2)
static_df_list

我想使用 static_df_1 和 static_df_2 中的值向每个数据框(dynamic_df_1 和 dynamic_df_2)添加一列,以执行计算,其中 dynamic_df_1 的计算使用 static_df_1 计算,dynamic_df_2 的计算使用 static_df_2 计算。

我想要的结果是这样的:

df_list[[1]] <- df_list[[1]] %>%
  mutate(z = dnorm(x = df_list[[1]]$x, mean = static_df_list$stat_df1$mu, sd = static_df_list$stat_df1$stdev))
df_list

df_list[[2]] <- df_list[[2]] %>%
  mutate(z = dnorm(x = df_list[[2]]$y, mean = static_df_list$stat_df2$mu, sd = static_df_list$stat_df2$stdev))
df_list

我可以采用循环方法,在我的真实代码中使用更复杂的函数:

for (i in 1:length(df_list)) {
    df_list[[i]]$z <- dnorm(x = df_list[[i]][[1]], mean = static_df_list[[i]]$mu, sd = static_df_list[[i]]$stdev)
}
df_list

我正在尝试找到一个跨数据帧计算的 lapply / map / mutate 类型的解决方案 - 想象一个数据帧网格,其目标是跨行计算。也对其他解决方案开放,例如具有嵌套值的单个 df,但还没有弄清楚如何做到这一点。

希望这很清楚 - 我已经尽力了! 谢谢!

【问题讨论】:

    标签: r for-loop dataframe lapply


    【解决方案1】:

    这个Map 解决方案似乎更简单。结果是identical()。创建df_list2df_list3 的代码如下。

    df_list4 <- df_list
    
    fun <- function(DF, Static_DF){
      DF[["z"]] = dnorm(DF[[1]], mean = Static_DF[["mu"]], sd = Static_DF[["stdev"]])
      DF
    }
    
    df_list4 <- Map(fun, df_list4, static_df_list)
    
    
    identical(df_list2, df_list3)
    #[1] TRUE
    
    identical(df_list2, df_list4)
    #[1] TRUE
    

    数据。

    运行创建初始df_list 的问题代码后,运行dplyr 管道和for 循环代码:

    df_list2 <- df_list
    
    df_list2[[1]] <- df_list2[[1]] %>%
      mutate(z = dnorm(x = df_list2[[1]]$x, mean = static_df_list$stat_df1$mu, sd = static_df_list$stat_df1$stdev))
    
    df_list2[[2]] <- df_list2[[2]] %>%
      mutate(z = dnorm(x = df_list2[[2]]$y, mean = static_df_list$stat_df2$mu, sd = static_df_list$stat_df2$stdev))
    
    
    df_list3 <- df_list
    
    for (i in 1:length(df_list3)) {
      df_list3[[i]]$z <- dnorm(x = df_list3[[i]][[1]], mean = static_df_list[[i]]$mu, sd = static_df_list[[i]]$stdev)
    }
    

    【讨论】:

    • 非常感谢,这是一个带有@Rui Barradas 函数的优雅解决方案:)。出于好奇,我查看了微基准测试 - 对于任何感兴趣的人:microbenchmark(Map(fun, df_list4, static_df_list), for (i in 1:length(df_list3)) { df_list3[[i]]$z &lt;- dnorm(x = df_list3[[i]][[1]], mean = static_df_list[[i]]$mu, sd = static_df_list[[i]]$stdev) })
    • # Unit: microseconds # expr min lq mean median uq max neval # Map 41.201 46.7005 71.32204 65.501 81.951 198.601 100 # loop 3583.002 4053.2015 4801.83906 4333.851 5067.651 12399.501 100 在大规模运行时可能会产生显着差异。关于格式的道歉......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-23
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多