【问题标题】:R: Apply function to calculate mean of a single column of dataframe across a listR:应用函数计算列表中单列数据框的平均值
【发布时间】:2018-01-10 19:34:42
【问题描述】:

一些样本数据

我有三个列表

    loc <- c("A","A","A","B","B","B")
    sub.loc <- c(1,2,3,1,2,3)

    set.seed(123)

    df1 <- as.data.frame(cbind(loc,sub.loc, round(rnorm(6),digits =2)))
    df2 <- as.data.frame(cbind(loc,sub.loc, round(rnorm(6),digits =2)))
    df3 <- as.data.frame(cbind(loc,sub.loc, round(rnorm(6),digits =2)))

    list.name <- list(df1,df2,df3)

我想生成一个具有第三列 V3 的均值和 sd 的文件。

Something like: 

    loc    sub.loc        V3                                      v4
    A        1        mean(c(-0.56,0.46,0.4))      sd(c(-0.56,0.46,0.4)) 
    A        2        mean(c(-0.23,-1.27,0.11))    sd(c(-0.23,-1.27,0.11))
    A        3        mean(c(-0.56,-0.69, 1.56))   sd(c(-0.56,-0.69, 1.56))
    B        1       mean(c(0.07,-0.45,1.79))      sd(c(0.07,-0.45,1.79))
    B        2        mean(c(0.13,1.22,0.5))       sd(c(0.13,1.22,0.5))
    B        3        mean(c(1.72,0.36,-1.97))     sd(c(1.72,0.36,-1.97))

我在 `V3`` 列中的实际数据有 NAs

我想用 lapply

    lapply(list.name, function(x) mean(x, na.rm = T))

    lapply(list.name, function(x) sd(x, na.rm = T))

但是他们两个都给了我 NAs

【问题讨论】:

    标签: r list apply lapply


    【解决方案1】:

    这可以通过dplyr 完成。首先,我不确定您上面的示例数据与实际数据的匹配程度如何,但现在您所有的“数字”值都是因素。你真的不应该在as.data.frame() 中使用cbind(),你可以不使用它。

    但是使用上面的示例数据,我们可以将数据堆叠到一个更大的 data.frame 中,然后执行一个简单的 group_by 以获得您想要的值

    library(dplyr)
    bind_rows(list.name, .id="from") %>% 
      mutate(V3=as.numeric(as.character(V3))) %>%  # fix the factors from the sample
      group_by(loc, sub.loc) %>% 
      summarize(mean=mean(V3, na.rm=T), sd=sd(V3, na.rm=T))
    

    【讨论】:

    • .id="from" 告诉bind_rows() 添加一个新列,以便我们知道来自列表的哪个元素的值相同。我现在意识到我们可能根本不需要那里。我猜对我来说只是习惯的力量。
    【解决方案2】:

    目前,您正在整个数据帧中运行 mean()sd(),其中包含非数字列,因此包含 NA

    考虑基本 R 的 bytapply 的面向对象的包装器),您首先使用 rbind 堆叠数据帧列表,然后跨 locsub.loc 运行聚合 分组:

    stackdf <- do.call(rbind, list.name)
    stackdf
    #    loc sub.loc    V3
    # 1    A       1 -0.56
    # 2    A       2 -0.23
    # 3    A       3  1.56
    # 4    B       1  0.07
    # 5    B       2  0.13
    # 6    B       3  1.72
    # 7    A       1  0.46
    # 8    A       2 -1.27
    # 9    A       3 -0.69
    # 10   B       1 -0.45
    # 11   B       2  1.22
    # 12   B       3  0.36
    # 13   A       1  0.40
    # 14   A       2  0.11
    # 15   A       3 -0.56
    # 16   B       1  1.79
    # 17   B       2  0.50
    # 18   B       3 -1.97
    
    dfs <- by(stackdf, stackdf[c("loc", "sub.loc")], FUN=function(df) {      
      data.frame(loc = df$loc[1],
                 sub.loc = df$sub.loc[1],
                 mean = mean(df$V3, na.rm=TRUE),
                 sd = sd(df$V3, na.rm=TRUE))
    })
    
    finaldf <- do.call(rbind, dfs)
    finaldf
    #   loc sub.loc        mean        sd
    # 1   A       1  0.10000000 0.5723635
    # 2   B       1  0.47000000 1.1723481
    # 3   A       2 -0.46333333 0.7189808
    # 4   B       2  0.61666667 0.5542863
    # 5   A       3  0.10333333 1.2631838
    # 6   B       3  0.03666667 1.8661279
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-02
      • 2017-12-04
      • 2021-11-22
      • 2014-03-29
      • 2021-11-25
      • 2023-03-29
      • 2016-03-03
      相关资源
      最近更新 更多