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)
我需要对 "count" 列求和,例如,当 S1 和 S3 共享相同的值(哪个值无关紧要),但没有其他列具有相同的值时。
在这个例子中,它应该 returns 值 11,因为我应该只考虑第 1 行和第 4 行中 "count" 列的值。
在第2、5、6行中,S1和S3的值相似,但我不想考虑它们,因为还有其他列具有相同的值。最后,不考虑第 3 行只是因为 S1 和 S3 具有不同的值。
我知道如何在 excel 中轻松地做到这一点,但我想知道如何在 R 中做到这一点。我已经尝试过 dplyr 的一些命令,但我失败了。
如果有人能提供帮助,我将不胜感激。
使用 dplyr
的解决方案。有两个步骤。第一个 filter
函数查找具有 S1 == S3
的行。第二个 filter_at
函数检查除 S1
、S3
和 count
之外的列均不等于 S1
,这应该与 [=17] 相同=] 在第一个 filter
函数之后。
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
使用 dplyr
、rowwise
、filter
:
library(dplyr)
df %>%
rowwise() %>%
filter(S1==S3 & !S1 %in% c(S2,S4,S5)) %>%
pull(count) %>%
sum()
# [1] 11
有点复杂,但它有效。仅使用 R 基础。从 this question 采取以简单方式比较多列的形式。
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
只选择一列数据帧,避免 "promotion to vector" 问题或省略 ,
这样:
sum(df[rowSums(sapply(df[equals],`==`,e2=df[equals[1]])) == length(equals) &
rowSums(sapply(df[not_equals],`==`,e2=df[equals[1]])) == 0, 1])
我正在尝试弄清楚如何从非常大的表(例如 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)
我需要对 "count" 列求和,例如,当 S1 和 S3 共享相同的值(哪个值无关紧要),但没有其他列具有相同的值时。
在这个例子中,它应该 returns 值 11,因为我应该只考虑第 1 行和第 4 行中 "count" 列的值。
在第2、5、6行中,S1和S3的值相似,但我不想考虑它们,因为还有其他列具有相同的值。最后,不考虑第 3 行只是因为 S1 和 S3 具有不同的值。
我知道如何在 excel 中轻松地做到这一点,但我想知道如何在 R 中做到这一点。我已经尝试过 dplyr 的一些命令,但我失败了。
如果有人能提供帮助,我将不胜感激。
使用 dplyr
的解决方案。有两个步骤。第一个 filter
函数查找具有 S1 == S3
的行。第二个 filter_at
函数检查除 S1
、S3
和 count
之外的列均不等于 S1
,这应该与 [=17] 相同=] 在第一个 filter
函数之后。
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
使用 dplyr
、rowwise
、filter
:
library(dplyr)
df %>%
rowwise() %>%
filter(S1==S3 & !S1 %in% c(S2,S4,S5)) %>%
pull(count) %>%
sum()
# [1] 11
有点复杂,但它有效。仅使用 R 基础。从 this question 采取以简单方式比较多列的形式。
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
只选择一列数据帧,避免 "promotion to vector" 问题或省略 ,
这样:
sum(df[rowSums(sapply(df[equals],`==`,e2=df[equals[1]])) == length(equals) &
rowSums(sapply(df[not_equals],`==`,e2=df[equals[1]])) == 0, 1])