簡體   English   中英

R 中的條件總和 – 多列

[英]Conditional sum in R – multiple columns

我試圖弄清楚如何從非常大的表(例如,30'000 行和 50 列)中提取一些特定信息。

想象一下我有這個數據框:

S1 <- c(1,2,1,1,3,1)
S2 <- c(2,1,3,2,1,1)
S3 <- c(1,2,2,1,3,1)
S4 <- c(3,3,4,2,3,1)
S5 <- c(3,2,5,3,2,2)
count <- c(10,5,3,1,1,1)
df <- data.frame(count,S1,S2,S3,S4,S5)

例如,當 S1 和 S3 共享相同的值(哪個值無關緊要)但沒有其他列具有相同的值時,我需要對“計數”列求和。

在這個例子中,它應該返回值 11,因為我應該只考慮第 1 行和第 4 行中“count”列的值。

在第 2、5 和 6 行中,S1 和 S3 具有相似的值,但我不想考慮它們,因為還有其他列具有相同的值。 最后,不要僅僅因為 S1 和 S3 具有不同的值就考慮第 3 行。

我知道如何在 excel 中輕松完成,但我想知道如何在 R 中完成它。我嘗試過來自 dplyr 的 somme 命令,但我失敗了。

如果你們中的任何人可以提供幫助,我將不勝感激。

使用dplyr的解決方案。 有兩個步驟。 第一個filter函數查找S1 == S3行。 第二個filter_at函數檢查除S1S3count所有列都不等於S1 ,這應該與第一個filter函數后的S3相同。

library(dplyr)

df2 <- df %>%
  filter(S1 == S3) %>%
  filter_at(vars(-S1, -S3, -count), all_vars(. != S1))
df2
  count S1 S2 S3 S4 S5
1    10  1  2  1  3  3
2     1  1  2  1  2  3

那么總計數如下。

sum(df2$count)
[1] 11

使用dplyrrowwisefilter

library(dplyr)
df %>%
  rowwise() %>%
  filter(S1==S3 & !S1 %in% c(S2,S4,S5)) %>% 
  pull(count) %>% 
  sum() 
# [1] 11

稍微復雜一點,但它有效。 僅使用 R 基礎。 這個問題采取以簡單方式比較多列的形式。

sum(df[df$S1==df$S3 & rowSums(sapply(df[,c(3,5,6)],`==`,e2=df$S1)) == 0,1])

[1] 11

最復雜的部分是如何檢查多個列。 在這種情況下,我們使用sapply將列c(3,5,6)通過相等 ( '==' ) 與 S1 進行比較,( e2==函數的第二個參數)。

正如 ycw 所提到的,通過向量定義所有列可能有點復雜,因此這種形式允許您檢查除我們不需要的列之外的所有列。

sum(df[df$S1==df$S3 & rowSums(sapply(df[,!(colnames(df) %in% c("count", "S1", "S3"))],`==`,e2=df$S1)) == 0,1])

對兩個比較應用相同的過程並僅定義相同值的向量:

equals <- c("S1", "S3")
not_equals <- !(colnames(df) %in% c("count", equals))

sum(df[rowSums(sapply(df[,equals,drop=FALSE],`==`,e2=df[equals[1]])) == length(equals) &
           rowSums(sapply(df[,not_equals,drop=FALSE],`==`,e2=df[equals[1]])) == 0, 1])

注意:使用drop=FALSE僅選擇數據框的一列,避免“提升到向量”問題或省略,這樣:

sum(df[rowSums(sapply(df[equals],`==`,e2=df[equals[1]])) == length(equals) &
           rowSums(sapply(df[not_equals],`==`,e2=df[equals[1]])) == 0, 1])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM