Cách thay thế NA bằng bộ giá trị


18

Tôi có khung dữ liệu sau:

library(dplyr)
library(tibble)


df <- tibble(
  source = c("a", "b", "c", "d", "e"),
  score = c(10, 5, NA, 3, NA ) ) 


df

Nó trông như thế này:

# A tibble: 5 x 2
  source score
  <chr>  <dbl>
1 a         10 . # current max value
2 b          5
3 c         NA
4 d          3
5 e         NA

Những gì tôi muốn làm là thay thế NAtrong cột điểm bằng các giá trị khác nhau cho hiện tại max + ntrở đi. Trong đó nphạm vi từ 1 đến tổng số hàng củadf

Kết quả trong việc này (mã hóa bằng tay):

  source score
  a         10
  b          5
  c         11 # obtained from 10 + 1
  d          3
  e         12 #  obtained from 10 + 2

Làm thế nào tôi có thể đạt được điều đó?

Câu trả lời:


8

Một lựa chọn khác:

transform(df, score = pmin(max(score, na.rm = TRUE) + 
                      cumsum(is.na(score)), score, na.rm = TRUE))

#  source score
#1      a    10
#2      b     5
#3      c    11
#4      d     3
#5      e    12

Nếu bạn muốn làm điều này trong dplyr

library(dplyr)
df %>% mutate(score = pmin(max(score, na.rm = TRUE) + 
                      cumsum(is.na(score)), score, na.rm = TRUE))

6

Một giải pháp cơ sở R

df$score[is.na(df$score)] <- seq(which(is.na(df$score))) + max(df$score,na.rm = TRUE)

như vậy mà

> df
# A tibble: 5 x 2
  source score
  <chr>  <dbl>
1 a         10
2 b          5
3 c         11
4 d          3
5 e         12

Đã ngắn gọn nhất nhưng có thể rút ngắn seq(which(is.na(df$score)))thành1:sum(is.na(df$score))
— sindri_baldur

@sindri_baldur cảm ơn. cái đó đã được cung cấp bởi stackoverflow.com/a/60222864/12158757
— ThomasIsCoding

6

Đây là một dplyrcách tiếp cận,

df %>% 
 mutate(score = replace(score, 
                       is.na(score), 
                       (max(score, na.rm = TRUE) + (cumsum(is.na(score))))[is.na(score)])
                       )

cái nào cho

# A tibble: 5 x 2
  source score
  <chr>  <dbl>
1 a         10
2 b          5
3 c         11
4 d          3
5 e         12

4

Với dplyr:

library(dplyr)

df %>%
  mutate_at("score", ~ ifelse(is.na(.), max(., na.rm = TRUE) + cumsum(is.na(.)), .))

Kết quả:

# A tibble: 5 x 2
  source score
  <chr>  <dbl>
1 a         10
2 b          5
3 c         11
4 d          3
5 e         12

3

Một dplyrgiải pháp.

df %>%
  mutate(na_count = cumsum(is.na(score)),
         score = ifelse(is.na(score), max(score, na.rm = TRUE) + na_count, score)) %>%
  select(-na_count)
## A tibble: 5 x 2
#  source score
#  <chr>  <dbl>
#1 a         10
#2 b          5
#3 c         11
#4 d          3
#5 e         12

2

Một cách khác, khá giống với giải pháp của ThomasIsCoding:

> df$score[is.na(df$score)]<-max(df$score, na.rm=T)+(1:sum(is.na(df$score)))
> df
# A tibble: 5 x 2
  source score
  <chr>  <dbl>
1 a         10
2 b          5
3 c         11
4 d          3
5 e         12

2

Không hoàn toàn thanh lịch so với các giải pháp cơ sở R, nhưng vẫn có thể:

library(data.table)
setDT(df)

max.score = df[, max(score, na.rm = TRUE)]
df[is.na(score), score :=(1:.N) + max.score]

Hoặc trong một dòng nhưng chậm hơn một chút:

df[is.na(score), score := (1:.N) + df[, max(score, na.rm = TRUE)]]
df
   source score
1:      a    10
2:      b     5
3:      c    11
4:      d     3
5:      e    12
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookie và Chính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.