我有一个数据框,我希望将每组的前两行相加,但如果这两个条目中的一个是零,则将其替换为下一个最低的非零值。此外,如果没有其他非零值,只需使sum = 0。我无法排序,所以这不是一个选择。
我有什么......
ID | Prod1
---|------
A | 2
A | 5
A | 9
B | 3
B | 0
B | 0
B | 8
B | 10
C | 0
C | 12
C | 0
C | 0
我想要的......
ID | Prod1
---|------
A | 7
B | 11
C | 0
数据
dput(df)
structure(list(ID = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L,
3L, 3L, 3L, 3L), .Label = c("A", "B", "C"), class = "factor"),
Prod1 = c(2L, 5L, 9L, 3L, 0L, 0L, 8L, 10L, 0L, 12L, 0L, 0L
)), .Names = c("ID", "Prod1"), class = "data.frame", row.names = c(NA,
-12L))
答案 0 :(得分:2)
以下是使用aggregate
的基本R方法。
dfAgg <- aggregate(Prod1~ID, data=df, function(i) sum(i[i != 0][1:2]))
这里,sum用i[i != 0][1:2]
给前两个非零元素。第一个[
子集i为非零元素(由i != 0
定义),然后第二个[
获取前两个这样的元素(由1:2
定义)。 / p>
function(i)
,以这种方式使用时称为匿名函数(python和函数编程称为lambda函数)。这是一个我们将在传递中使用的函数,并且不希望给它起一个名字。如果所有元素都为0,则sum
返回NA。该行返回
dfAgg
ID Prod1
1 A 7
2 B 11
3 C NA
现在,填写NAs
dfAgg$Prod1[is.na(dfAgg$Prod1)] <- 0
dfAgg
ID Prod1
1 A 7
2 B 11
3 C 0