在R

时间:2016-05-25 20:50:47

标签: r dataframe mean data-manipulation

我真的不知道从哪里开始,所以我在这里问。我有两个数据框:

set.seed(21)
DF1 <- data.frame(year = c(seq(2000,2012,by=1)), 
              C1 = runif(13,0,1),
              C2 = runif(13,0,1),
              C3 = runif(13,0,1),
              C4 = runif(13,0,1),
              C5 = runif(13,0,1))

DF2 <- data.frame(column = c("C1", "C2", "C3", "C4", "C5"),
              start = c(2005,2001,2006,2005,2009),
              end = c(2012,2009,2011,2010,2012))

我需要编写一个包含以下步骤的函数:

  1. 对于DF2中的每一行: 取DF2 $列中的相应列并从DF1取平均值。

    例如:在DF1 $ C1中,取2005和2012之间的平均值

  2. 报告:DF2 [1,1],DF2 [1,2],DF2 [1,3],均值1

  3. 小于可用数据的值,例如:2002 - 5 = 1997但在DF1中不可用,可以作为NA。

    示例输出:

        > DF2.out
          column start  end        m1 
        1     C1  2005 2012 0.9186834 
        2     C2  2001 2009        NA 
    

    提前感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

我假设您的问题是通过您在另一个数据框中的参数来总结一个数据框。在这种情况下,下面的代码将有助于第1部分。

library(dplyr)

apply.by.colname <- function(data, col.name, year.start, year.end) {

    data %>% 
        filter(year >= year.start & year <= year.end) %>% 
        select(matches(col.name))
}

new.df <- apply.by.colname(DF1, "C1", 2005, 2012)
sapply(new.df, mean)

对于完整的解决方案,您可能需要在其他自定义函数或apply调用中使用此函数。

答案 1 :(得分:1)

您可以使用select id, type_id, status,created_at from device where id = 8710; 将循环包裹在mapply行:

DF2

答案 2 :(得分:0)

如果我正确解释了您的问题,以下示例应该为您提供您想要的内容,如果您想要的是DF1中每列的每个列在DF2中作为年份范围的子集之后的平均值:

# get the column names from DF2$column
c_list <- as.character(DF2$column)

# for each column name in c_list, store the start and end
# year, and find the mean of the column subset by year range
ml <- do.call(rbind, lapply(1:length(c_list), function(x){

  start <- DF2[x, "start"]
    end <- DF2[x, "end"]

  mean(DF1[DF1$year >= start & DF1$year <= end,  c_list[x]])

}))

# join the means with DF2
DF2.out <- cbind(DF2, ml)

> DF2.out
  column start  end        ml
1     C1  2005 2012 0.5861268
2     C2  2001 2009 0.3942018
3     C3  2006 2011 0.5853924
4     C4  2005 2010 0.4904493
5     C5  2009 2012 0.6783216

答案 3 :(得分:0)

使用mapply的另一种尝试应该非常快,因为它只是一些矩阵索引并选择:

column <- match(DF2$column, names(DF1) )
start  <- match(DF2$start, DF1$year)
end    <- match(DF2$end, DF1$year)

m1 <- mapply(
  function(r1,r2,co) mean(DF1[cbind(seq(r1,r2), co)]),
  start,
  end,
  column 
)

data.frame(
  column=names(DF1)[column], 
  start=DF1$year[start],
  end=DF1$year[end],
  m1
)

#  column start  end        m1
#1     C1  2005 2012 0.5861268
#2     C2  2001 2009 0.3942018
#3     C3  2006 2011 0.5853924
#4     C4  2005 2010 0.4904493
#5     C5  2009 2012 0.6783216