簡體   English   中英

用R中最接近的條件值替換行值

[英]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列中的一些原始值locNumbnewlocNumb

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.1locNumb.1是原始值, pred_triplocNumb是最接近的正值。 您可以排除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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM