我对R还是很陌生,尽管我已经处理了一些数据,但我对如何解决这个问题完全不知所措。到目前为止,Google和SO搜索并没有帮助我。很抱歉,如果这是重复的,请为我指出正确的解决方案。
我有一个包含2列的df,分别称为id和seq。像这样
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
我需要计算seq列中相等元素之间不相等元素的数量,例如1和1或3和3等之间有多少个元素。该元素的第一个实例应为NaN,因为在此之前没有要计数的元素。如果下一个元素相同,则应仅编码0,因为不存在不等式中间的元素,例如1和1。结果应写在新列中,例如延迟。
一个要注意的是,一旦在id列(此处为1和2)中开始了新的id,就必须重新开始此过程。
这就是我希望输出的内容:
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
我真的希望有人能够帮助我解决这个问题,并让我了解更多有关此的信息。
答案 0 :(得分:5)
一个简单的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
答案 1 :(得分:2)
这里有可能在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.
一些进一步的解释:
我们将行按id
分组,然后将my.function
应用于列seq
中的条目。这样可以确保我们分别处理具有不同id
的行。
my.function
接受数字条目的向量,检查先前的相等条目,并返回当前和先前的相等条目之间的距离减去一(即,计算两者之间的元素数)。
my.function
使用两个for
循环,但这应该很快,因为我们不会动态地增长任何向量(ret
已预先分配在{{1的开头}}),并且一旦遇到相等的元素,我们就会中断内部循环。
答案 2 :(得分:1)
尝试:
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),]
df
get_lead <- function(x) {
x <- as.character(x)
l <- list(unique(x))
res <- rep(NA, length(x))
for (i in seq_along(x)) {
if (!is.null(l[[x[i] ]])) {
res[i] <- (i - l[[x[i] ]] - 1)
}
l[[x[i] ]] <- i
}
res
}
df$delay <- unlist(lapply(split(df$seq, df$id), get_lead))
df
# 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
答案 3 :(得分:0)
这是方法: -write函数查找哪一行从索引的第一行开始 -写入功能,可计算不同数字的数量与最新的重复数字 -将函数应用于所有行并分配给可变延迟
Indstart <- function(j,df){
ind_start <- min(which(df[1:j,1]==df[j,1]))
}
difval <- function( j, df){
i <- Indstart(j, df)
pos_j_pr <- ifelse(length(which(df[i:(j-1),2]==df[j,2]))>0, max(which(df[i:(j-1),2]==df[j,2])) + i-1, 0)
non_rep_num <- ifelse(pos_j_pr>0, sum(df[pos_j_pr:j,2] != df[j,2]), "NA")
return(non_rep_num)
}
for (j in 1:length(df[,1])){
df$delay[j] <- difval(j,df)
}