整个上午我一直在制动我的头脑怎么做。 所以我们说这是我的数据集
set.seed(1)
temp <- as.data.frame(cbind(Key = letters[1:5], sapply(1:12, function(x) sample(c(0, 1), 5, replace = T))))
names(temp)[2:13] <- month.abb
temp
# Key Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
# 1 a 0 1 0 0 1 0 0 1 1 1 0 0
# 2 b 0 1 0 1 0 0 1 1 1 0 1 0
# 3 c 1 1 1 1 1 0 0 0 1 0 0 1
# 4 d 1 1 0 0 0 1 0 1 1 1 0 1
# 5 e 0 0 1 1 0 0 1 0 1 1 0 0
我要做的是连续两个月计算出现次数(1s
)。
例如,c
和d
出现在Jan
。两者都出现在Feb
中,因此本月的输出将为1
。在Feb
中,a-d
出现了c
,但Mar
中只有.25
,因此该月的输出将为data.frame(Month = month.abb[1:11], OverlapPercent = c(1, 1/4, 1, 1/3, 0, 0, 1/2, 1, 3/5, 0, 0))
# Month OverlapPercent
# 1 Jan 1.0000000
# 2 Feb 0.2500000
# 3 Mar 1.0000000
# 4 Apr 0.3333333
# 5 May 0.0000000
# 6 Jun 0.0000000
# 7 Jul 0.5000000
# 8 Aug 1.0000000
# 9 Sep 0.6000000
# 10 Oct 0.0000000
# 11 Nov 0.0000000
,等等。 / p>
该迷你示例的所需输出:
rle
正在考虑一些如何使用{{1}},但不确定如何强制它每次停止两次出现
答案 0 :(得分:3)
除非我遗漏了某些内容,否则以下内容有效:
#just to remove 'factor's from "temp"
tmp = do.call(cbind.data.frame, c(temp[1], lapply(temp[-1], function(x) as.numeric(as.character(x)))))
sapply(head(seq_len(ncol(tmp))[-1], -1),
function(i) sum(tmp[[i]] & tmp[[i+1]]) / sum(tmp[[i]]))
#[1] 1.0000000 0.2500000 1.0000000 0.3333333 0.0000000 0.0000000 0.5000000 1.0000000 0.6000000 0.0000000 0.0000000
修改强> 出于好奇,我检查了@Bathsheba&#34;按位AND&#34;速度似乎比&#34;逻辑AND&#34;:
更快#identical results
sapply(head(seq_len(ncol(tmp))[-1], -1),
function(i) sum(bitwAnd(tmp[[i]], tmp[[i+1]])) / sum(tmp[[i]]))
#[1] 1.0000000 0.2500000 1.0000000 0.3333333 0.0000000 0.0000000 0.5000000 1.0000000 0.6000000 0.0000000 0.0000000
#twice as fast
x1 = sample(0:1, 1e6, T); x2 = sample(0:1, 1e6, T)
identical(sum(x1 & x2) / sum(x1), sum(bitwAnd(x1, x2)) / sum(x1))
#[1] TRUE
microbenchmark(sum(x1 & x2) / sum(x1), sum(bitwAnd(x1, x2)) / sum(x1), times = 50)
#Unit: milliseconds
# expr min lq median uq max neval
# sum(x1 & x2)/sum(x1) 23.95648 25.32448 25.78471 26.56232 49.18491 50
# sum(bitwAnd(x1, x2))/sum(x1) 10.97982 11.07309 11.20237 13.00450 35.67963 50
答案 1 :(得分:2)
在伪代码中,将每列表示为二进制数。
E.g。 Jan = 0b00110和Feb = 0b11110。
您的Jan公式是
Bitcount(Jan AND Feb) / Bitcount(Jan)
其中AND
是按位AND
运算符,Bitcount
计算数字中的1位数。 (如果需要,我可以提供一种计数方式)。当然,其他月份的公式是一个微不足道的概括。
显然,你需要一个分支,因为分母为零:在你的问题中没有明确定义。
答案 2 :(得分:2)
首先修复temp
,使0/1列为数字而不是因子。然后将overlap
应用于每对列:
temp[-1] <- lapply(temp[-1], function(x) as.numeric(as.character(x)))
overlap <- function(x, y) mean(y[x == 1])
data.frame(Month = month.abb[-12],
Overlap = sapply(2:12, function(i) overlap(temp[,i], temp[,i+1])))
以上是优选的,因为它保持溶液的独立部分分开;但是,作为替代方案,我们可以省略上面的第一行(这会修复因素),而是将其合并到overlap
中,如下所示:
overlap <- function(x, y) mean(as.numeric(as.character(y))[x == 1]
请注意,重叠是分数(根据问题中显示的输出),而不是问题中的标题所示的百分比。
答案 3 :(得分:0)
length(which(!xor(data["Feb"],data["Mar"]) & data["Feb"]==1)) / length(which(data["Feb"]==1))
!xor
是否定的独占或。
length(which(...))
给出逻辑向量中的真值数。