R:使用if / else在列表中追加具有不同长度的对象的列

我试图将一列值附加到R列表的元素,其中每个元素的长度各不相同.这是一个示例列表foo:

A   B   C   
1   1   150
1   2   25
1   4   30
2   1   200
2   3   15
3   4   30

首先,我将foo分解为列表foo,其元素基于A的每个唯一值.现在,我想写一个函数a)对A的每个值的C值求和,但b)在B时排除B == 4. c)将总和作为新的列D附加,并且d)C除以D以产生比例(列E).最终,它将结合在一个新的df中,看起来像:

A   B   C   D   E
1   1   150 175 0.857
1   2   25  175 0.143
1   4   30  175 0.171
2   1   200 215 0.930
2   3   15  215 0.070
3   4   30  0   0/NA

但是,我遇到了问题,因为在某些情况下,对于给定的A值,只有B == 4(这里,A == 3)的情况,所以当我尝试将C除以D时,我得到了错误消息.

有没有办法将if / else语句合并到函数中,这样当A是唯一的并且B的唯一可能值是4时,将跳过该操作并在附加列中放置一个默认的非零值?

将df子集设置为B == 4的排除情况使得后面的操作更加困难,但是包括B == 4的情况使得总和/比例计算不准确.

任何帮助表示赞赏!这是当前的代码:

goo <- lapply(foo,function(df){
  df$D <- sum(df$C, na.rm = TRUE)
  df$E <- df$C / df$D
  ###  .....
  df
})
最佳答案
这是我如何使用dplyr做到这一点

library(dplyr)
newfoo <- foo %>%
  group_by(A) %>%
  mutate(D = sum(C[B != 4]),
         E = C/D)
#newfoo                   # the resulting data.frame
#Source: local data frame [6 x 5]
#Groups: A
#
#  A B   C   D          E
#1 1 1 150 175 0.85714286
#2 1 2  25 175 0.14285714
#3 1 4  30 175 0.17142857
#4 2 1 200 215 0.93023256
#5 2 3  15 215 0.06976744
#6 3 4  30   0        Inf

或者如果你想避免使用Inf,你可以像这样使用ifelse:

newfoo <- foo %>%
  group_by(A) %>%
  mutate(D = sum(C[B != 4]),
         E = ifelse(D == 0, 0, C/D))
#Source: local data frame [6 x 5]
#Groups: A
#
#  A B   C   D          E
#1 1 1 150 175 0.85714286
#2 1 2  25 175 0.14285714
#3 1 4  30 175 0.17142857
#4 2 1 200 215 0.93023256
#5 2 3  15 215 0.06976744
#6 3 4  30   0 0.00000000

转载注明原文:R:使用if / else在列表中追加具有不同长度的对象的列 - 代码日志