计算R中列表中分配的数据帧中的变量总和,考虑其他变量的不同条件

时间:2013-12-22 01:16:07

标签: r plyr lapply

大家好我正在使用R中的数据框列表。列表中的RES非常棒,但我想解决这个问题。我有一个名为global的列表,它有五个数据帧f1,f2,f3,f4,f5每个数据帧都有一个名为CreditValue的主要变量,而像f1这样的标志的变量有{{1}一个标志变量CreditValue,其值为1. b1有两个标志变量f2,其值为1,b1的值为2. b2有三个标志变量f3,值为1,b1,值为2; b2,值为3. b3有四个标志变量f4,带值1,b1,其值为2,b2,其值为3; b3,其值为4. b4有五个标志变量f5,其值为1,b1的值为2,b2的值为3,b3的值为4,b4的值为5.标志变量始终从第3列开始所有数据帧。我希望考虑到标志变量的不同方面,计算每个数据帧中b5的总和。我的列表有下一个结构(我在最后部分包括CreditValue版本):

dput

我使用global $f1 KeyID CreditValue b1 1 001 1 1 2 002 2 1 3 003 3 1 4 004 4 1 5 005 5 1 6 006 6 1 7 007 7 1 8 009 8 1 9 010 9 1 $f2 KeyID CreditValue b1 b2 1 001 1 1 2 2 002 2 1 2 3 003 3 NA 2 4 004 4 NA 2 5 005 5 NA 2 6 006 6 1 2 7 007 7 1 2 8 009 8 NA 2 9 010 9 1 2 10 011 10 NA 2 11 012 11 1 2 $f3 KeyID CreditValue b1 b2 b3 1 001 1 1 2 3 2 002 2 1 2 3 3 003 3 1 2 3 4 004 4 1 2 3 5 005 5 NA 2 3 6 006 6 NA 2 3 7 007 7 1 2 3 8 009 8 1 2 3 9 010 9 NA NA 3 10 011 10 NA NA 3 11 012 11 NA 2 3 12 013 11 1 2 3 13 014 11 NA NA 3 $f4 KeyID CreditValue b1 b2 b3 b4 1 001 1 NA 2 3 4 2 002 2 NA 2 3 4 3 003 3 NA NA NA 4 4 004 4 NA NA NA 4 5 005 5 NA NA NA 4 6 006 6 1 2 3 4 7 007 7 1 2 3 4 8 009 8 1 2 3 4 9 010 9 1 2 3 4 10 011 10 1 2 3 4 11 012 11 1 2 3 4 12 013 11 1 2 3 4 13 014 11 1 2 3 4 14 015 12 1 NA 3 4 15 016 12 1 NA 3 4 $f5 KeyID CreditValue b1 b2 b3 b4 b5 1 001 1 1 2 3 4 5 2 002 2 1 2 3 4 5 3 003 3 1 2 3 4 5 4 004 4 1 2 3 4 5 5 005 5 NA NA 3 4 5 6 006 6 1 2 3 4 5 7 007 7 1 2 3 4 5 8 009 8 1 2 3 4 5 9 010 9 1 2 3 4 5 10 011 10 NA NA NA NA 5 11 012 11 1 2 3 4 5 12 013 11 1 2 3 4 5 13 014 11 1 2 3 4 5 14 015 12 1 2 3 4 5 15 016 12 1 2 3 4 5 16 017 14 NA NA NA 4 5 17 018 14 NA NA NA 4 5 函数形式llply()包来处理R中的列表,但我不知道如何定义一个函数来实现它。我使用这个代码计算总和,但如果我有更多的数据帧,它将是如此复杂。我还想考虑标志变量(5)将这些值保存在新的数据帧或矩阵中。总和的结果是下一个:

plyr

这些总和是根据所有数据框中考虑sum(f1$CreditValue[f1[,3]==1]) [1] 45 sum(f2$CreditValue[f2[,3]==1],na.rm=TRUE) [1] 36 sum(f3$CreditValue[f3[,3]==1],na.rm=TRUE) [1] 36 sum(f4$CreditValue[f4[,3]==1],na.rm=TRUE) [1] 97 sum(f5$CreditValue[f5[,3]==1],na.rm=TRUE) [1] 97 变量的公式计算的。

b1

这些总和是根据所有数据框中考虑sum(f2$CreditValue[is.na(f2[,3]) & f2[,4]==2] ,na.rm=TRUE) [1] 30 sum(f3$CreditValue[is.na(f3[,3]) & f3[,4]==2] ,na.rm=TRUE) [1] 22 sum(f4$CreditValue[is.na(f4[,3]) & f4[,4]==2] ,na.rm=TRUE) [1] 3 sum(f5$CreditValue[is.na(f5[,3]) & f5[,4]==2] ,na.rm=TRUE) [1] 0 b2变量值的公式计算的。这里存在b1(第3列)值的条件。

b1

这些总和是根据所有数据框中考虑sum(f3$CreditValue[is.na(f3[,3]) & is.na(f3[,4]) & f3[,5]==3] ,na.rm=TRUE) [1] 30 sum(f4$CreditValue[is.na(f4[,3]) & is.na(f4[,4]) & f4[,5]==3] ,na.rm=TRUE) [1] 0 sum(f5$CreditValue[is.na(f5[,3]) & is.na(f5[,4]) & f5[,5]==3] ,na.rm=TRUE) [1] 5 b3b2变量值的公式计算的。现在存在b1b1值的条件(第3,4列)。

b2

这些总和是根据所有数据框中考虑sum(f4$CreditValue[is.na(f4[,3]) & is.na(f4[,4]) & is.na(f4[,5]) & f4[,6]==4] ,na.rm=TRUE) [1] 12 sum(f5$CreditValue[is.na(f5[,3]) & is.na(f5[,4]) & is.na(f5[,5]) & f5[,6]==4] ,na.rm=TRUE) [1] 28 b4b3b2变量的值的公式计算的。现在存在b1b1b2值的条件(第3,4,5列)。

b3

在考虑所有数据帧中sum(f5$CreditValue[is.na(f5[,3]) & is.na(f5[,4]) & is.na(f5[,5]) & is.na(f5[,6]) & f5[,7]==5] ,na.rm=TRUE) [1] 10 b5b4b3b2变量的值的情况下,使用最后一个公式计算此总和。现在,b1b1b2b3的值存在一个条件(第3,4,5,6列)。

显示的总和是很多代码的结果,但是我想创建一个对标志变量(b4)起作用的函数来计算总和。我不知道是否可以使用b1, b2, b3, b4, b5或与forllply一起使用的功能来实现此功能。我试图恢复这样的代码:

lapply

使用此代码:

sum(f5$CreditValue[is.na(f5[,3]) & is.na(f5[,4]) & is.na(f5[,5]) & is.na(f5[,6]) & f5[,7]==5] ,na.rm=TRUE) 

但它不起作用,因为在原始条件下,我只考虑每个数据帧中的特定行,并且恢复的代码不会这样做。我想将总和的结果保存在一个新的数据框中,矩阵如下:

sum(f5$CreditValue[is.na(f5[,3,4,5,6]) & f5[,7]==5] ,na.rm=TRUE)

最后一个数据帧中的零是由于所有数据帧都没有所有标志变量而产生的,例如 f1 f2 f3 f4 f5 f1 45 0 0 0 0 f2 36 30 0 0 0 f3 36 22 30 0 0 f4 97 3 0 12 0 f5 97 0 5 28 10 只有f1且它没有b1之类的b2,b3,b4,b5。我的列表的f5版本是下一个版本:

dput

我希望你能帮助我,因为它构建一个计算总和的函数是如此复杂,如果我使用传统形式的代码,我会遇到更多数据框列表的问题。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

您可以使用lapply并调用构建输出数据框行的函数:

get.sums = function(df) {
  sapply(1:5, function(y) {
    if (y > 1) {
      na.col = 3:(y+1)
    } else {
      na.col = NULL
    }
    if (paste0("b", y) %in% names(df)) {
      return(sum(df$CreditValue[rowSums(!is.na(df[,na.col,drop=F])) == 0 & df[,(y+2)] == y], na.rm=T))
    } else {
      return(0)
    }
  })
}
rows = lapply(global, get.sums)
sums = do.call(rbind, rows)
sums
#    [,1] [,2] [,3] [,4] [,5]
# f1   45    0    0    0    0
# f2   36   30    0    0    0
# f3   36   22   30    0    0
# f4   97    3    0   12    0
# f5   97    0    5   28   10