我对R很新,虽然我已经完成了一些数据争论,但我对如何解决这个问题完全不知所措.到目前为止,Google和SO搜索并没有让我感到满意.如果这是重复的,我很抱歉,那么请指出我正确的解决方案.
我有一个名为id和seq的2列df.像这样
set.seed(12)
id <- rep(c(1:2),10)
seq<-sample(c(1:4),20,replace=T)
df <- data.frame(id,seq)
df <- df[order(df$id),]
id seq
1 1 1
3 1 4
5 1 1
7 1 1
9 1 1
11 1 2
13 1 2
15 1 2
17 1 2
19 1 3
2 2 4
4 2 2
6 2 1
8 2 3
10 2 1
12 2 4
14 2 2
16 2 2
18 2 3
20 2 1
Run Code Online (Sandbox Code Playgroud)
我需要计算seq列中相等元素之间的不等元素的数量,例如,在1和1或3和3之间有多少元素等.元素的第一个实例应该是NaN,因为在此之前没有元素如果下一个元素是相同的,它应该只编码0,因为中间没有不相等的元素,例如1和1.结果应该写在新的列中,例如延迟.
一个问题是,一旦在id列中开始新的id(此处:1和2),此过程将不得不重新开始.
这是我希望输出的内容:
id seq delay
1 1 1 NA
3 1 4 NA
5 1 1 1
7 1 1 0
9 1 1 0
11 1 2 NA
13 1 2 0
15 1 2 0
17 1 2 0
19 1 3 NA
2 2 4 NA
4 2 2 NA
6 2 1 NA
8 2 3 NA
10 2 1 1
12 2 4 4
14 2 2 4
16 2 2 0
18 2 3 4
20 2 1 4
Run Code Online (Sandbox Code Playgroud)
我真的希望有人能够帮助我解决这个问题并让我了解更多相关信息.
简单的dplyr解决方案:
df %>%
mutate(row = 1:n()) %>%
group_by(id, seq) %>%
mutate(delay = row - lag(row) - 1) %>%
select(-row)
# # A tibble: 20 x 3
# # Groups: id, seq [8]
# id seq delay
# <int> <int> <dbl>
# 1 1 1 NA
# 2 1 4 NA
# 3 1 1 1
# 4 1 1 0
# 5 1 1 0
# 6 1 2 NA
# 7 1 2 0
# 8 1 2 0
# 9 1 2 0
# 10 1 3 NA
# 11 2 4 NA
# 12 2 2 NA
# 13 2 1 NA
# 14 2 3 NA
# 15 2 1 1
# 16 2 4 4
# 17 2 2 4
# 18 2 2 0
# 19 2 3 4
# 20 2 1 4
Run Code Online (Sandbox Code Playgroud)
dplyr这是在链中使用自定义函数的可能性
my.function <- function(x) {
ret <- rep(NA, length(x))
for (i in 2:length(x)) {
for (j in (i-1):1) {
if (x[j] == x[i]) {
ret[i] = i - j - 1
break
}
}
}
return(ret)
}
library(dplyr)
df %>%
group_by(id) %>%
mutate(delay = my.function(seq))
## A tibble: 20 x 3
## Groups: id [2]
# id seq delay
# <int> <int> <dbl>
# 1 1 1 NA
# 2 1 4 NA
# 3 1 1 1.
# 4 1 1 0.
# 5 1 1 0.
# 6 1 2 NA
# 7 1 2 0.
# 8 1 2 0.
# 9 1 2 0.
#10 1 3 NA
#11 2 4 NA
#12 2 2 NA
#13 2 1 NA
#14 2 3 NA
#15 2 1 1.
#16 2 4 4.
#17 2 2 4.
#18 2 2 0.
#19 2 3 4.
#20 2 1 4.
Run Code Online (Sandbox Code Playgroud)
一些进一步的解释:
我们对行进行分组id,然后应用于my.function列 中的条目seq。这确保我们id单独处理具有不同 s 的行。
my.function接受一个数字条目向量,检查先前的相等条目,并返回当前和前一个相等条目之间的距离减一(即计算之间的元素数量)。
my.function使用两个for循环,但这应该很快,因为我们不会动态增长任何向量(ret在 的开头预先分配my.function),并且一旦遇到相等的元素,我们就会中断内部循环。