R 按顺序计数列
R Count Sequentially Columns
set.seed(0)
data = data.frame(ID = 1:1000, X1=runif(1000), X2=runif(1000), DROP1=sample(0:1,r=T),DROP2=sample(0:1,r=T),DROP3=sample(0:1,r=T))
说这是我的数据。我想这样做:计算 DROP1 等于 1 的值的个数;然后统计DROP2的值在DROP1等于1的情况中的个数;然后计算 DROP2 等于 1 和 DROP1 等于 1 的情况中 DROP3 等于 1 的值的数量。我可以手动执行此操作,但我们的真实数据文件很大并且有 80+ DROP 变量。理想的输出只是一个看起来像的打印输出:
DROP1, #
DROP2 (AFTER DROP1), #
DROP3 (AFTER DROP1 & DROP2), #
这是一个带有 base R
的选项,我们使用 grep
获得 'DROP' 列名称 ('nm1')。然后遍历这些序列,得到那些的 seq
,对数据列进行子集化,使用 Reduce
得到一个带有 &
的逻辑向量(只有当我们有所有列时才为 TRUE 1 行,即 1=> TRUE,0 => FALSE),并将这些元素的 sum
计算为 return 计数
nm1 <- grep('^DROP', names(data), value = TRUE)
sapply(seq_along(nm1), function(i) {i1 <- seq(i)
sum(Reduce(`&`, data[nm1[i1]])) })
#[1] 503 249 137
或 data.table
library(data.table)
setDT(data)
lapply(seq_along(nm1), function(i) {
i1 <- seq(i)
data[, sum(Reduce(`&`, .SD)), .SDcols = nm1[i1]]
})
数据
set.seed(0)
data <- data.frame(ID = 1:1000, X1=runif(1000), X2=runif(1000),
DROP1=sample(0:1,1000, replace = TRUE),
DROP2=sample(0:1,1000, replace = TRUE),
DROP3=sample(0:1,1000,replace = TRUE))
另一种选择:
set.seed(0)
data = data.frame(ID = 1:1000, X1=runif(1000), X2=runif(1000), DROP1=sample(0:1,1000,r=T),DROP2=sample(0:1,1000,r=T),DROP3=sample(0:1,1000,r=T))
tb <- table(data[,4:6])
tb
# , , DROP3 = 0
# DROP2
# DROP1 0 1
# 0 108 126
# 1 118 112
# , , DROP3 = 1
# DROP2
# DROP1 0 1
# 0 128 135
# 1 136 137
sum(tb[2,,])
# [1] 503
sum(tb[2,2,])
# [1] 249
sum(tb[2,2,2])
# [1] 137
证明,体力劳动:
sum(with(data, DROP1 == 1L))
# [1] 503
sum(with(data, DROP1 == 1L & DROP2 == 1L))
# [1] 249
sum(with(data, DROP1 == 1L & DROP2 == 1L & DROP3 == 1L))
# [1] 137
set.seed(0)
data = data.frame(ID = 1:1000, X1=runif(1000), X2=runif(1000), DROP1=sample(0:1,r=T),DROP2=sample(0:1,r=T),DROP3=sample(0:1,r=T))
说这是我的数据。我想这样做:计算 DROP1 等于 1 的值的个数;然后统计DROP2的值在DROP1等于1的情况中的个数;然后计算 DROP2 等于 1 和 DROP1 等于 1 的情况中 DROP3 等于 1 的值的数量。我可以手动执行此操作,但我们的真实数据文件很大并且有 80+ DROP 变量。理想的输出只是一个看起来像的打印输出:
DROP1, #
DROP2 (AFTER DROP1), #
DROP3 (AFTER DROP1 & DROP2), #
这是一个带有 base R
的选项,我们使用 grep
获得 'DROP' 列名称 ('nm1')。然后遍历这些序列,得到那些的 seq
,对数据列进行子集化,使用 Reduce
得到一个带有 &
的逻辑向量(只有当我们有所有列时才为 TRUE 1 行,即 1=> TRUE,0 => FALSE),并将这些元素的 sum
计算为 return 计数
nm1 <- grep('^DROP', names(data), value = TRUE)
sapply(seq_along(nm1), function(i) {i1 <- seq(i)
sum(Reduce(`&`, data[nm1[i1]])) })
#[1] 503 249 137
或 data.table
library(data.table)
setDT(data)
lapply(seq_along(nm1), function(i) {
i1 <- seq(i)
data[, sum(Reduce(`&`, .SD)), .SDcols = nm1[i1]]
})
数据
set.seed(0)
data <- data.frame(ID = 1:1000, X1=runif(1000), X2=runif(1000),
DROP1=sample(0:1,1000, replace = TRUE),
DROP2=sample(0:1,1000, replace = TRUE),
DROP3=sample(0:1,1000,replace = TRUE))
另一种选择:
set.seed(0)
data = data.frame(ID = 1:1000, X1=runif(1000), X2=runif(1000), DROP1=sample(0:1,1000,r=T),DROP2=sample(0:1,1000,r=T),DROP3=sample(0:1,1000,r=T))
tb <- table(data[,4:6])
tb
# , , DROP3 = 0
# DROP2
# DROP1 0 1
# 0 108 126
# 1 118 112
# , , DROP3 = 1
# DROP2
# DROP1 0 1
# 0 128 135
# 1 136 137
sum(tb[2,,])
# [1] 503
sum(tb[2,2,])
# [1] 249
sum(tb[2,2,2])
# [1] 137
证明,体力劳动:
sum(with(data, DROP1 == 1L))
# [1] 503
sum(with(data, DROP1 == 1L & DROP2 == 1L))
# [1] 249
sum(with(data, DROP1 == 1L & DROP2 == 1L & DROP3 == 1L))
# [1] 137