R 根据多列中以下行中的值更新行

R 根据多列中以下行中的值更新行,r,dplyr,R,Dplyr,我有一个数据框,有几千行,选择了两列,例如: col1 col2 2 11 3 11 4 12 4 1 5 1 6 2 1 3 1 3 2 4 在每列中,某个点的值重置为1,然后继续累积到某个值,然后再次重置。每列中的重置点彼此独立。我需要的是一个函数,用于检测重置并在此重置之前更新值,根据其自身的重置情况,每个列的负值从-1到-3。因此,需要的结果是: col1 col2 2 -3 3 -2 4

我有一个数据框,有几千行,选择了两列,例如:

col1  col2
2     11
3     11
4     12
4     1
5     1
6     2
1     3
1     3
2     4
在每列中,某个点的值重置为1,然后继续累积到某个值,然后再次重置。每列中的重置点彼此独立。我需要的是一个函数,用于检测重置并在此重置之前更新值,根据其自身的重置情况,每个列的负值从-1到-3。因此,需要的结果是:

col1  col2
2     -3
3     -2
4     -1
-3     1
-2     1
-1     2
1     3
1     3
2     4

有什么建议可以这样做吗?(Dplyr解决方案最受欢迎)

像这样的怎么样

f <- function(x) {
    idx <- which(x == 1 & dplyr::lag(x) != 1);
    for (i in 1:length(idx)) x[seq(idx[i] - 3, idx[i] - 1)] <- -3:-1;
    return(x);
}

df[] <- lapply(df, f);
#   col1 col2
#1    2   -3
#2    3   -2
#3    4   -1
#4   -3    1
#5   -2    1
#6   -1    2
#7    1    3
#8    1    3
#9    2    4

使用
dplyr
zoo
,您可以这样做

library(zoo)
df2 <- df %>% mutate_all(~pmin(., rollapply(c(diff(.)<0, NA), #find reset point
                                            3, #roll window
                                            function(x) -which(x)[1], #dist to next reset
                                            fill=NA,
                                            align="left"),
                               na.rm=TRUE)) #only replaces non-NA values
df2
  col1 col2
1    2   -3
2    3   -2
3    4   -1
4   -3    1
5   -2    1
6   -1    2
7    1    3
8    1    3
9    2    4
图书馆(动物园)

df2%突变\u all(~pmin(.),rollapply(c(diff(.)另一种碱基R溶液:

mydf[] <- lapply(mydf, function(x) {
  w <- which(x == 1 & c(0, head(x,-1)) != 1)
  x[c(sapply(w, `-`, 3:1))] <- -3:-1
  x
})

旧答案:

mydf[] <- lapply(mydf, function(x) {
  w <- which(x == 1)
  i <- c(0, diff(w)) != 1
  w <- c(sapply(w[i], `-`, 3:1))
  x[w] <- -3:-1
  x
})

mydf[]这里有一个基本的R方法:

df[] <- lapply(df, function(x) replace(x, which(sign(diff(x)) < 0) - 0:2, -(1:3)))

df
#   col1 col2
# 1    2   -3
# 2    3   -2
# 3    4   -1
# 4   -3    1
# 5   -2    1
# 6   -1    2
# 7    1    3
# 8    1    3
# 9    2    4

df[]如果只有3个滞后,那么在什么情况下也可以:

library(dplyr)

d <- tbl_df(read.table(text = "col1  col2
2     11
3     11
4     12
4     1
5     1
6     2
1     3
1     3
2     4", stringsAsFactors = FALSE, header = TRUE ))

d %>%  
  mutate_all(funs(case_when((. > lead(., 1) ~ -1L),
                            (. > lead(., 2) ~ -2L),
                            (. > lead(., 3) ~ -3L),
                            TRUE ~ .)))
库(dplyr)
d%
突变所有(funs(当(.>lead(,1)~-1L时的情况),
(.>铅(,,2)~-2L),
(.>铅(,,3)~-3L),
对~))
您可以使用
lag()
lead()
函数
df[] <- lapply(df, function(x) replace(x, which(sign(diff(x)) < 0) - 0:2, -(1:3)))

df
#   col1 col2
# 1    2   -3
# 2    3   -2
# 3    4   -1
# 4   -3    1
# 5   -2    1
# 6   -1    2
# 7    1    3
# 8    1    3
# 9    2    4
library(dplyr)

d <- tbl_df(read.table(text = "col1  col2
2     11
3     11
4     12
4     1
5     1
6     2
1     3
1     3
2     4", stringsAsFactors = FALSE, header = TRUE ))

d %>%  
  mutate_all(funs(case_when((. > lead(., 1) ~ -1L),
                            (. > lead(., 2) ~ -2L),
                            (. > lead(., 3) ~ -3L),
                            TRUE ~ .)))