2017-02-10 115 views
1

我有一個數據框,我想總結每個組的前2行,但是如果這2個條目中的一個條目爲零,則將其替換爲下一個最低的非零值。另外,如果沒有其他非零值來使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 

DATA

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)) 

回答

2

下面是使用aggregate一個基礎R方法。

dfAgg <- aggregate(Prod1~ID, data=df, function(i) sum(i[i != 0][1:2])) 

這裏,總和是用i[i != 0][1:2]加上前兩個非零元素。第一個[將子集i分配給非零元素(由i != 0定義),然後第二個[取前兩個這樣的元素(由1:2定義)。

function(i),當以這種方式使用時稱爲匿名函數(python和函數式編程稱爲lambda函數)。這是我們將用來傳遞的一個函數,不想給它命名。如果所有元素均爲0,則sum返回NA。這條線返回

dfAgg 
    ID Prod1 
1 A  7 
2 B 11 
3 C NA 

現在,填寫來港

dfAgg$Prod1[is.na(dfAgg$Prod1)] <- 0 

dfAgg 
    ID Prod1 
1 A  7 
2 B 11 
3 C  0 
+1

尼斯。我不認爲這種方式能夠滿足所有的條件,而我在C組中獲得12分,因此我不會這樣做,因此我寫的「髒」功能:) – Sotos

+1

是的。我試着在'sum'中使用na.rm = TRUE,並在最終輸出中獲得了12。我想這意味着R用0代替了c組中的i [!= 0] [1:2]中的NA,而不是默認生成的NA。 – lmo

+0

這工作完美!非常感謝。我越來越熟悉聚合函數,但它在代碼中的意思是(函數(i)sum(i [i!= 0] [1:2])?從我見過的函數(i)只是說你要給我一個函數,而我是你的變量,我只是不理解代碼對sum(i [i!= 0] [1:2])所說的話。理解我!= 0意味着我不等於零。另外,如果我只是想在一行中的兩個條目的總和將函數說sum(i [1:2])?對不起,長的評論只是想進一步我理解 – PVic