2017-06-03 67 views
0

我想通過對考慮多個條件的值進行求和來構建一個新變量(以及另外一個,請參見下文)。在這裏你可以看到R代碼,直到像我目前的問題。如何通過有條件求和來填充新的數據幀列

# The raw dataframe 
area <- c("A", "A", "B", "A", "C", "B", "A", "B", "A", "C") 
varclass <- c("Z1", "Z1", "Z1", "Z2", "Z1", "Z1", "Z2", "Z1", "Z2", "Z2") 
count <- c(45, 56, 2, 8, 345, 3, 98, 2, 6, 9) 

df1 <- data.frame(area, 
        varclass, 
        count, 
        stringsAsFactors = FALSE) 
df1 
# See how df1 looks like... 
# area varclass count 
#1  A  Z1 45 
#2  A  Z1 56 
#3  B  Z1  2 
#4  A  Z2  8 
#5  C  Z1 345 
#6  B  Z1  3 
#7  A  Z2 98 
#8  B  Z1  2 
#9  A  Z2  6 
#10 C  Z2  9 

# Building the final dataframe 

df2 <- data.frame(unique(df1$area), 
        stringsAsFactors = FALSE) 
names(df2)[1] <- "area" 
# See how df2 looks like... 
# area 
#1 A 
#2 B 
#3 C 

# The new variable to build 

df2$Z1_sum <- sum(df1[df1$varclass == "Z1" & df1$area == df2$area,]$count) 
# doesn't work 

# See what I hope 
# area Z1_sum 
#1 A  101 
#2 B  7 
#3 C  345 

正如你在最後一行看到的,我想在df2數據庫中建立一個新的變量Z1_sum。 Z1_sum是df1數據庫的計數總和,其中varclass = "Z1"df1$area符合當前行的值(在MS Excel中,表示使用LC1或$ A2單元ID)。

請考慮一個事實,即我並不是在尋找解決方案,通過使用條件組或者dcast函數來直接構建df2中的df2 ...我只想要一個公式,該公式允許我返回正確的值我的新專欄。這是我的額外條件。爲什麼?這是因爲我接下來要用最複雜的公式來構建其他變量而不僅僅是一筆總和。通過了解如何進行這種有條件的操作,我希望繼續...

感謝您的幫助。

傑夫

回答

0

你的意思是:

df2 <- setNames(
       aggregate(
          count ~ area, 
          df1[df1$varclass == "Z1", ], 
          sum 
         ), 
       c("area", "Z1_sum") 
       ) 
df2 
    area Z1_sum 
1 A 101 
2 B  7 
3 C 345 

df2$Z1_sum <- aggregate(count ~ area, df1[df1$varclass == "Z1", ], sum)$count 

編輯解決您的評論。

嘗試:

df2 <- aggregate(
       count ~ area + varclass, 
       df1, 
       sum 
       ) 

,這將使你在「長」格式的數據:

df2 
    area varclass count 
1 A  Z1 101 
2 B  Z1  7 
3 C  Z1 345 
4 A  Z2 112 
5 C  Z2  9 

現在,你需要把它重塑使用類似的「寬」格式:

df2 <- xtabs(count ~ area + varclass, df2) 
    varclass 
area Z1 Z2 
    A 101 112 
    B 7 0 
    C 345 9 

或:

df2 <- reshape(df2, idvar = "area", timevar = "varclass", direction = "wide") 
    area count.Z1 count.Z2 
1 A  101  112 
2 B  7  NA 
3 C  345  9 
+0

謝謝。第一項提案正常,但與羅馬的提案相同。你的第二個對我來說很準確,但不適用於我的數據集。我收到錯誤消息:「$ < - 。data.frame'中的錯誤('* tmp *',AZ_tx,value = c(96L,24L,84L,12L,:替換有105行,數據有322」)。 –

+0

這是真的。有可能克服它嗎?其他想法?我最初寧願添加一個像「&df1 $ area == ??」這樣的參數。哪裏?考慮到輸出行給出df2 $區域的相對值... –

+0

非常感謝您的編輯。這是很不錯的。但是,我不想重新設計/更改數據框,因爲我希望在最後填充更多複雜操作的新列。承認我希望在一步中創建「newvar2」,結果是將Z1_sum除以Z2_sum並乘以100 ... –

0

只是基於你想要計入最終總和的Z *的子集。

df1Z1 <- df1[df1$varclass %in% c("Z1"), ] 
aggregate(count ~ area, data = df1Z1, FUN = sum) 

    area count 
1 A 101 
2 B  7 
3 C 345 
+0

謝謝羅馬。這對於一個鏡頭來說工作得很好,但是我不知道如何用一個以上的新列填充數據框df2。考慮到Z1_sum是我想用填充函數填充df2數據框的許多新列(Z2_sum等)之一,在我看來,我必須構建許多中間數據框並稍後將它合併爲一個...我錯了嗎? –

0

可以使用dplyr得到你想要的結果:

library(dplyr) 

df2 <- group_by(df1, area) %>% 
    filter(varclass == "Z1") %>% 
    summarize(Z1_sum = sum(count)) %>% 
df2 
#> # A tibble: 3 x 2 
#> area Z1_sum 
#> <chr> <dbl> 
#> 1  A 101 
#> 2  B  7 
#> 3  C 345 

dplyr動詞應該是相當自明,%>%是管工作,以從一個函數的輸出,並使其成爲第一輸入到下一個。 group_by這裏的分組由area所以當我們計算總和時(在summarize)它是每個區域組的總和。 filter將數據分組。

+0

謝謝。包dplyr很棒! –