我正在尝试将一列值附加到 R 列表的元素中,其中每个元素的长度各不相同。这是一个示例列表 foo:
A B C
1 1 150
1 2 25
1 4 30
2 1 200
2 3 15
3 4 30
首先,我根据 A 的每个唯一值将 foo 拆分为包含元素的列表 foo。现在,我想编写一个函数,a) 将 C 的值与 A 的每个值相加,但是 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 将列附加到具有不同长度对象的列表中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26348929/