[英]R - Replacing values in a matrix row conditional on the values in one of the columns
[英]Replacing row values with the closest conditional values in R
在R中,我遇到的問題類似於此處介紹的問題: 用最接近的值替換R中的NA 。 但是,差異在於我想要更改的值不是NA而是任何小於0的值,並且更改這些值還取決於另一列中的值(因此需要添加條件語句)。 我無法理解如何使該問題中提出的一些解決方案適應我的問題。 由於我有大量數據,所以這很快也很重要。
樣本數據
pred_trip <- c(0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1)
locNumb <- c(-1,-1,-1,-1,-1,2,2,2,2,3,3,0,0,0,4,4,4,4,-1,-1,-1,-1,-1,0,0,0,0,0,0,5,5,5,5)
df <- data.frame(pred_trip, locNumb)
因此,如果locNumb列中的值<= 0並且pred_trip列中存在0,則locNumb列中的值將重新分配給大於0的最接近值。
期望的輸出:
pred_trip locNumb
1 0 2
2 0 2
3 0 2
4 0 2
5 0 2
6 1 2
7 1 2
8 1 2
9 1 2
10 0 3
11 0 3
12 0 3
13 1 0
14 1 0
15 1 4
16 0 4
17 0 4
18 0 4
19 0 4
20 0 4
21 0 4
22 0 4
23 0 4
24 0 4
25 0 4
26 0 4
27 1 0
28 1 0
29 1 0
30 1 5
31 1 5
32 1 5
33 1 5
我在類似的解決方案中調整代碼時遇到了麻煩,因為它依賴於is.na並且不包括我需要的任何其他條件。 但是在偽代碼中是這樣的:(不知道在我的其他條件語句中添加的地方如果pred_trip == 0。
f1 <- function(df) {
N <- length(df)
na.pos <- which(df$locNumb < 0 (df))
if (length(na.pos) %in% c(0, N)) {
return(df)
}
non.na.pos <- which(!df$locNumb < 0(df))
intervals <- findInterval(na.pos, non.na.pos,
all.inside = TRUE)
left.pos <- non.na.pos[pmax(1, intervals)]
right.pos <- non.na.pos[pmin(N, intervals+1)]
left.dist <- na.pos - left.pos
right.dist <- right.pos - na.pos
df[na.pos] <- ifelse(left.dist <= right.dist,
df[left.pos], df[right.pos])
return(df)
}
這是一種方法。
rle
將為您提供行程編碼,您可以使用NA
替換負值,然后使用zoo
包中的na.locf
函數向前移動(並向后移動)最近的非負值。 最后, inverse.rle
函數可以創建所需的向量,我們可以將其添加到原始data.frame df
作為newlocNumb
至於任何附加條件可用於將locNumb
列中的一些原始值locNumb
為newlocNumb
列
require(zoo)
pred_trip <- c(0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1)
locNumb <- c(-1, -1, -1, -1, -1, 2, 2, 2, 2, 3, 3, 0, 0, 0, 4, 4, 4, 4, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5)
df <- data.frame(pred_trip, locNumb)
RLE <- rle(df$locNumb)
RLE
## Run Length Encoding
## lengths: int [1:8] 5 4 2 3 4 5 6 4
## values : num [1:8] -1 2 3 0 4 -1 0 5
RLE$values[RLE$values < 0] <- NA
while (any(is.na(RLE$values))) {
RLE$values <- na.locf(na.locf(RLE$values, na.rm = FALSE), fromLast = TRUE, na.rm = FALSE)
}
df$newlocNumb <- inverse.rle(RLE)
df
## pred_trip locNumb newlocNumb
## 1 0 -1 2
## 2 0 -1 2
## 3 0 -1 2
## 4 0 -1 2
## 5 0 -1 2
## 6 1 2 2
## 7 1 2 2
## 8 1 2 2
## 9 1 2 2
## 10 0 3 3
## 11 0 3 3
## 12 0 0 0
## 13 1 0 0
## 14 1 0 0
## 15 1 4 4
## 16 0 4 4
## 17 0 4 4
## 18 0 4 4
## 19 0 -1 4
## 20 0 -1 4
## 21 0 -1 4
## 22 0 -1 4
## 23 0 -1 4
## 24 0 0 0
## 25 0 0 0
## 26 0 0 0
## 27 1 0 0
## 28 1 0 0
## 29 1 0 0
## 30 1 5 5
## 31 1 5 5
## 32 1 5 5
## 33 1 5 5
data.table
庫,在內存使用方面非常有效btw,可以在這里使用 -
library(data.table)
# converting data.frame to data.table
dt <- data.table(df)
#assigning unique id to each row
dt[,grpno := .I]
# getting all the unique values from the data.table where locNumb > 0
positivelocNumb <- unique(dt[locNumb > 0])
# indexing by grpno, this will be used to help define nearest positive locnumb
setkeyv(positivelocNumb,c('grpno'))
setkeyv(dt,c('grpno'))
# nearest positive value join
dt2 <- positivelocNumb[dt, roll = "nearest"]
輸出,其中pred_trip.1
和locNumb.1
是原始值, pred_trip
和locNumb
是最接近的正值。 您可以排除pred_trip
從合並是通過創建列positivelocNumb
作為unique(dt[locNumb > 0,list(locNumb,grpno)])
-
> dt2
grpno pred_trip locNumb pred_trip.1 locNumb.1
1: 1 1 2 0 -1
2: 2 1 2 0 -1
3: 3 1 2 0 -1
4: 4 1 2 0 -1
5: 5 1 2 0 -1
6: 6 1 2 1 2
7: 7 1 2 1 2
8: 8 1 2 1 2
9: 9 1 2 1 2
10: 10 0 3 0 3
11: 11 0 3 0 3
12: 12 0 3 0 0
13: 13 0 3 1 0
14: 14 1 4 1 0
15: 15 1 4 1 4
16: 16 0 4 0 4
17: 17 0 4 0 4
18: 18 0 4 0 4
19: 19 0 4 0 -1
20: 20 0 4 0 -1
21: 21 0 4 0 -1
22: 22 0 4 0 -1
23: 23 0 4 0 -1
24: 24 0 4 0 0
25: 25 1 5 0 0
26: 26 1 5 0 0
27: 27 1 5 1 0
28: 28 1 5 1 0
29: 29 1 5 1 0
30: 30 1 5 1 5
31: 31 1 5 1 5
32: 32 1 5 1 5
33: 33 1 5 1 5
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.