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 ~ .)))