首页 文章

使用嵌套for循环在R中创建数据框

提问于
浏览
2

我正在寻找一种方法来使用两个for循环在R中创建一个特定的数据框 . 我开始使用一个函数,但是遇到了一些困难 . 第一个for循环将循环遍历数据帧列表的名称,第二个for循环将循环遍历每个数据帧的列并返回平均值 . 然后输出将返回一个数据帧,每行包含一个数据帧的列的平均值 . 这是一些虚拟数据:

first<- data.frame(b = factor(c("Hi", "Hi","Hi","Hi")), y = c(8, 3, 9, 9),
               z = c(1, 1, 1, 2))
second<- data.frame(b = factor(c("Med", "Med", "Med", "Med")),y = c(3, 2, 6, 5),
                z = c(1, 11, 4, 3))

third<- list(first,second)
fourth<- c("first","second")
names(third)<- c(fourth)
fifth<- c("y","z")

这是我正在处理的功能:

testr<- function(arg1,arg2){
  a<- list()
  for(i in 1:length(arg1)){
   b<- (third[[arg1[i]]])
    for(j in 1:length(arg2)){
      c<- mean(b[[arg2[[j]]]])
      a[[j]]<-c
    }
  }
  df<- do.call("cbind",a)
  df<-as.data.frame(df)
  df$name<- arg1
  return(df)
}

我的目标是这个结果:

testr(fourth,fifth)

    V1   V2  name
1 7.25 1.25 first
2    4 4.75 second

但相反,我得到了这个:

testr(fourth,fifth)

 Error in `$<-.data.frame`(`*tmp*`, "name", value = c("first", "second" : 
  replacement has 2 rows, data has 1

任何帮助将不胜感激!

2 回答

  • 1

    假设您有许多这样的数据帧如 firstsecond 以及如下所示的此类数据帧列表,您可以使用 dplyr 获得所需的结果,如下所示:

    library(dplyr)
    l <- list(first, second)
    df <- do.call(rbind, l)
    df %>% group_by(b) %>% summarise_each(funs(mean))
    

    输出是:

    Source: local data frame [2 x 3]
    
           b     y     z
      (fctr) (dbl) (dbl)
    1     Hi  7.25  1.25
    2    Med  4.00  4.75
    
  • 1

    我的建议......让我们一起避免循环 . 看起来你只想要两列的平均值和data.frame的名称 .

    通过 dplyrdata.table 获取一些技巧,使这种类型的摘要变得微不足道 .

    library(dplyr)
    third %>% 
      bind_rows(.id = "name") %>% 
      group_by(name) %>% 
      summarize(
        V1 = mean(y), 
        V2 = mean(z))
    
    # Source: local data frame [2 x 3]
    #
    #     name    V1    V2
    #    (chr) (dbl) (dbl)
    # 1  first  7.25  1.25
    # 2 second  4.00  4.75
    
    
    library(data.table)
    dt <- rbindlist(third)
    dt[,list(V1 = mean(y),V2 = mean(z)),by = b]
    #      b   V1   V2
    # 1:  Hi 7.25 1.25
    # 2: Med 4.00 4.75
    
    # or as David points out.
    dt[, lapply(.SD, mean), by = b]
    #      b    y    z
    # 1:  Hi 7.25 1.25
    # 2: Med 4.00 4.75
    

相关问题