sum() 或其他方法对数据帧子集中的 TRUE 进行计数

sum() or other method to count TRUEs in a subset of a dataframe

提问人:Robert Hadow 提问时间:4/29/2019 更新时间:4/29/2019 访问量:2157

问:

我有一个 5000 x 8000 的数据帧,其中大部分是逻辑值。我想计算各种矩形部分的 TRUE 值。完美的解决方案如下所示:

features.total <- sum(df[ , 651:8500])

唉,那行不通。以下是一些可以玩的例子:

aa <- bb <- cc <- dd <- rep.int(FALSE,4)
df1 <- data.frame(aa, bb, cc, dd, stringsAsFactors = FALSE)
df1[2:3,2:3] <- TRUE

ww <- xx <- yy <- zz <- rep.int(0,4)
df2 <- data.frame(ww, xx, yy, zz, stringsAsFactors = FALSE)
df2[2:3,2:3] <- 1

v0 <- c(FALSE, TRUE, TRUE, TRUE)
v1 <- as.vector(df1[2, ])
v2 <- c(0, 1, 1, 0)

sum() 适用于您期望的那些,但适用于其他的:

FUN(X[[i]], ...) 中的错误:仅在数据框上定义,所有 数值变量

  • sum(v0)工作正常
  • sum(v1)失败
  • sum(v2)工作正常
  • sum(df1)失败
  • sum(df2)工作正常

逻辑对象更小、更简单。有没有一种替代方法可以让我坚持使用 TRUE 和 FALSE,但满足添加区域的需要?

r 数据帧 求和 逻辑运算符

评论


答:

0赞 jay.sf 4/29/2019 #1

sum仅在具有所有数值变量的数据框上定义。如果我们看一下模式,我们会看到在 s 处失败,即列出的逻辑对象 ()。sumdata.frame$

str(v0) # works fine
# logi [1:4] FALSE TRUE TRUE TRUE

# compare:
str(as.data.frame(v0))
# 'data.frame': 4 obs. of  1 variable:
#  $ v0: logi  FALSE TRUE TRUE TRUE

str(v1) # fails
# 'data.frame': 1 obs. of  4 variables:
# $ aa: logi FALSE
# $ bb: logi TRUE
# $ cc: logi TRUE
# $ dd: logi FALSE

str(v2) # works fine
# num [1:4] 0 1 1 0

str(df1) # fails
# 'data.frame': 4 obs. of  4 variables:
# $ aa: logi  FALSE FALSE FALSE FALSE
# $ bb: logi  FALSE TRUE TRUE FALSE
# $ cc: logi  FALSE TRUE TRUE FALSE
# $ dd: logi  FALSE FALSE FALSE FALSE

str(df2) # works fine
# 'data.frame': 4 obs. of  4 variables:
# $ ww: num  0 0 0 0
# $ xx: num  0 1 1 0
# $ yy: num  0 1 1 0
# $ zz: num  0 0 0 0

当我们他们时,它工作正常。unlist

str(v1) # fails
sum(unlist(v1)) # works fine
# [1] 2

str(df1) # fails
sum(unlist(df1)) # works fine
# [1] 4

而不是我们也可以转换之前的 s,只需摆脱列表结构即可。unlistdata.frameas.matrixsum

sum(as.matrix(v1))
# [1] 2
sum(as.matrix(df1))
# [1] 4

甚至更短......

sum(t(t(v1)))
# [1] 2
sum(t(t(df1)))
# [1] 4

...

sum(!(v1))
# [1] 2

sum(!!(df1))
# [1] 4

编辑

像这样申请data.frame

df1
#   a b    l1   l2    l3
# 1 t z  TRUE TRUE  TRUE
# 2 b a FALSE TRUE  TRUE
# 3 h j FALSE TRUE FALSE
# 4 c x  TRUE TRUE  TRUE

str(df1)
# 'data.frame': 4 obs. of  5 variables:
#  $ a : Factor w/ 4 levels "b","d","e","x": 3 2 1 4
#  $ b : Factor w/ 4 levels "c","r","w","x": 2 1 4 3
#  $ l1: logi  FALSE FALSE TRUE TRUE
#  $ l2: logi  TRUE TRUE TRUE TRUE
#  $ l3: logi  FALSE TRUE FALSE TRUE

我们可以像这样建立矩形sum

sum(!!df1[3:5])
sum(!!df1[sapply(df1, is.logical)])  # or, allocating logical columns automatically 
# [1] 8
sum(!!df1[3:4, 4:5])  # or, sub-rectangles
# [1] 3

数据

df1 <- structure(list(a = structure(c(3L, 2L, 1L, 4L), .Label = c("b", 
"d", "e", "x"), class = "factor"), b = structure(c(2L, 1L, 4L, 
3L), .Label = c("c", "r", "w", "x"), class = "factor"), l1 = c(FALSE, 
FALSE, TRUE, TRUE), l2 = c(TRUE, TRUE, TRUE, TRUE), l3 = c(FALSE, 
TRUE, FALSE, TRUE)), class = "data.frame", row.names = c(NA, 
-4L))

评论

0赞 Robert Hadow 4/29/2019
谢谢jay.sf。我的数据帧还有其他字符数据列,因此转到矩阵不起作用。还有四列列表-- 这是Excel电子表格的不幸遗留物,数据来自此。我正在逐个观察地将它们列出。它们正在填充数据帧的稀疏逻辑区域。完成后,我将按照您的建议取消列出整个数据帧。我永远感激你。
0赞 jay.sf 4/29/2019
我不确定您是否真的在处理列表内对象顺序,而不是列表内的向量。我在编辑中举了一个例子来回答我的问题,即我认为您的数据框可能是什么样子的,以及如何获得整个矩形的总和,而不是列。如果你需要按列求和,你可能需要 @julian-hn 建议的。colSums
1赞 Julian_Hn 4/29/2019 #2

除了 jay 建议的手动取消列表并转换为 jay 建议之外,我们还可以使用一些专门设计的 R 函数,例如: 和。这些函数在每一行/每一列上工作,因此隐式地将其参数转换为向量,并为其定义了总和。完成此操作后,对于每一行/每列,我们可以对结果求和以获得总和。matrixdata.framesrowSums()colSums()data.frame

aa <- bb <- cc <- dd <- rep.int(FALSE,4)
df1 <- data.frame(aa, bb, cc, dd, stringsAsFactors = FALSE)
df1[2:3,2:3] <- TRUE

ww <- xx <- yy <- zz <- rep.int(0,4)
df2 <- data.frame(ww, xx, yy, zz, stringsAsFactors = FALSE)
df2[2:3,2:3] <- 1

v0 <- c(FALSE, TRUE, TRUE, TRUE)
v1 <- as.vector(df1[2, ])
v2 <- c(0, 1, 1, 0)

######### working code

> sum(colSums(v1))
[1] 2

> sum(colSums(df1))
[1] 4

评论

1赞 Robert Hadow 4/29/2019
像冠军一样工作。 处理所有列表和问题。sum(colSums(df[ ,651:8500]))$