সর্বশেষ নন-এনএ মান সহ এনএগুলি প্রতিস্থাপন


141

একটি ডেটা.ফ্রেমে (বা ডেটা টেটেবল), আমি নিকটবর্তী পূর্ববর্তী নন-এনএ মান সহ এনএগুলি "পূরণ করতে" চাই। একটি সহজ উদাহরণ, ভেক্টর ব্যবহার করে (ক এর পরিবর্তে data.frame) নিম্নলিখিত:

> y <- c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA)

আমি এমন একটি ফাংশন চাই fill.NAs()যা আমাকে এমন নির্মাণ করতে দেয় yy:

> yy
[1] NA NA NA  2  2  2  2  3  3  3  4  4

আমাকে অনেকগুলি (মোট ~ 1 টিবি) ছোট আকারের data.frame(-30-50 এমবি) এর জন্য এই ক্রিয়াকলাপটি পুনরাবৃত্তি করতে হবে , যেখানে একটি সারির এনএ হ'ল সমস্ত প্রবেশিকা রয়েছে। সমস্যাটির কাছে যাওয়ার ভাল উপায় কী?

আমি যে কুৎসিত সমাধানটি রান্না করেছি তা এই ফাংশনটি ব্যবহার করে:

last <- function (x){
    x[length(x)]
}    

fill.NAs <- function(isNA){
if (isNA[1] == 1) {
    isNA[1:max({which(isNA==0)[1]-1},1)] <- 0 # first is NAs 
                                              # can't be forward filled
}
isNA.neg <- isNA.pos <- isNA.diff <- diff(isNA)
isNA.pos[isNA.diff < 0] <- 0
isNA.neg[isNA.diff > 0] <- 0
which.isNA.neg <- which(as.logical(isNA.neg))
if (length(which.isNA.neg)==0) return(NULL) # generates warnings later, but works
which.isNA.pos <- which(as.logical(isNA.pos))
which.isNA <- which(as.logical(isNA))
if (length(which.isNA.neg)==length(which.isNA.pos)){
    replacement <- rep(which.isNA.pos[2:length(which.isNA.neg)], 
                                which.isNA.neg[2:max(length(which.isNA.neg)-1,2)] - 
                                which.isNA.pos[1:max(length(which.isNA.neg)-1,1)])      
    replacement <- c(replacement, rep(last(which.isNA.pos), last(which.isNA) - last(which.isNA.pos)))
} else {
    replacement <- rep(which.isNA.pos[1:length(which.isNA.neg)], which.isNA.neg - which.isNA.pos[1:length(which.isNA.neg)])     
    replacement <- c(replacement, rep(last(which.isNA.pos), last(which.isNA) - last(which.isNA.pos)))
}
replacement
}

ফাংশনটি fill.NAsনিম্নরূপ ব্যবহৃত হয়:

y <- c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA)
isNA <- as.numeric(is.na(y))
replacement <- fill.NAs(isNA)
if (length(replacement)){
which.isNA <- which(as.logical(isNA))
to.replace <- which.isNA[which(isNA==0)[1]:length(which.isNA)]
y[to.replace] <- y[replacement]
} 

আউটপুট

> y
[1] NA  2  2  2  2  3  3  3  4  4  4

... যা কাজ করে বলে মনে হচ্ছে। কিন্তু, মানুষ, এটা কি কুরুচিপূর্ণ! কোনও পরামর্শ?


1
এটির পরে অন্যান্য প্রশ্ন থেকে, আমি মনে করি আপনি এখন এটি roll=TRUEসন্ধান করেছেন data.table
ম্যাট ডাওল

3
একটি নতুন পদ্ধতি হিসেবে চালু করা হচ্ছে fillR
Saksham

14
এছাড়াও, দেখুন tidyr::fill()
zx8754

উত্তর:


160

আপনি সম্ভবত চিড়িয়াখানা প্যাকেজ na.locf()থেকে ফাংশনটি আপনার এনএ মানগুলি প্রতিস্থাপনের জন্য শেষ পর্যবেক্ষণটি এগিয়ে নিয়ে যেতে চান।

সহায়তা পৃষ্ঠা থেকে এটির ব্যবহারের উদাহরণটি এখানে:

library(zoo)

az <- zoo(1:6)

bz <- zoo(c(2,NA,1,4,5,2))

na.locf(bz)
1 2 3 4 5 6 
2 2 1 4 5 2 

na.locf(bz, fromLast = TRUE)
1 2 3 4 5 6 
2 1 1 4 5 2 

cz <- zoo(c(NA,9,3,2,3,2))

na.locf(cz)
2 3 4 5 6 
9 3 2 3 2 

2
এছাড়াও লক্ষ করুন যে na.locfচিড়িয়াখানায় সাধারণ ভেক্টর পাশাপাশি চিড়িয়াখানার জিনিসগুলি নিয়ে কাজ করে। এর na.rmযুক্তি কিছু অ্যাপ্লিকেশনগুলিতে কার্যকর হতে পারে।
জি গ্রোথেনডিক

5
na.locf(cz, na.rm=FALSE)নেতৃস্থানীয় রাখতে ব্যবহার করুন NA
বলপয়েন্টবেন

@ বালপয়েন্টপেনের মন্তব্য গুরুত্বপূর্ণ এবং উত্তরে অন্তর্ভুক্ত করা উচিত। ধন্যবাদ!
বেন

62

একটি পুরানো প্রশ্ন খননের জন্য দুঃখিত। ট্রেনে এই কাজটি করার জন্য আমি ফাংশনটি সন্ধান করতে পারি নি, তাই আমি নিজে একটি লিখেছিলাম।

আমি এটি গর্বিত যে এটি একটি সামান্য বিট দ্রুত।
যদিও এটি কম নমনীয়।

তবে এটি আমার সাথে খুব ভাল খেলেছে ave

repeat.before = function(x) {   # repeats the last non NA value. Keeps leading NA
    ind = which(!is.na(x))      # get positions of nonmissing values
    if(is.na(x[1]))             # if it begins with a missing, add the 
          ind = c(1,ind)        # first position to the indices
    rep(x[ind], times = diff(   # repeat the values at these indices
       c(ind, length(x) + 1) )) # diffing the indices + length yields how often 
}                               # they need to be repeated

x = c(NA,NA,'a',NA,NA,NA,NA,NA,NA,NA,NA,'b','c','d',NA,NA,NA,NA,NA,'e')  
xx = rep(x, 1000000)  
system.time({ yzoo = na.locf(xx,na.rm=F)})  
## user  system elapsed   
## 2.754   0.667   3.406   
system.time({ yrep = repeat.before(xx)})  
## user  system elapsed   
## 0.597   0.199   0.793   

সম্পাদন করা

এটি আমার সবচেয়ে উজ্জীবিত উত্তর হয়ে যাওয়ার সাথে সাথে আমাকে প্রায়ই মনে করিয়ে দেওয়া হয়েছিল যে আমি নিজের ফাংশনটি ব্যবহার করি না, কারণ আমার প্রায়শই চিড়িয়াখানার maxgapযুক্তি প্রয়োজন need চিড়িয়াখানায় প্রান্তের ক্ষেত্রে কিছু অদ্ভুত সমস্যা রয়েছে যখন আমি dplyr + তারিখগুলি ব্যবহার করি যেগুলি আমি ডিবাগ করতে পারি না, আমি আমার পুরানো ফাংশনটি উন্নত করার জন্য আজই এটিতে ফিরে এসেছি।

আমি আমার উন্নত ফাংশন এবং অন্যান্য সমস্ত এন্ট্রি এখানে বেঞ্চমার্ক করেছি। বৈশিষ্ট্যগুলির বুনিয়াদী সেটগুলির জন্য, tidyr::fillদ্রুততম এবং প্রান্তের ক্ষেত্রে ব্যর্থ না হয়েও। @ ব্র্যান্ডনবার্টেলসেনের আরসিপিপি প্রবেশ দ্রুততর তবে এটি ইনপুটটির ধরণের সম্পর্কে জটিল নয় (তিনি ভুল বোঝাবুঝির কারণে প্রান্তের কেসগুলি ভুলভাবে পরীক্ষা করেছিলেন all.equal)।

আপনার যদি প্রয়োজন maxgapহয় তবে নীচের আমার ফাংশনটি চিড়িয়াখানার চেয়ে দ্রুত (এবং তারিখগুলির সাথে অদ্ভুত সমস্যা নেই)।

আমি আমার পরীক্ষার ডকুমেন্টেশন রেখেছি

নতুন ফাংশন

repeat_last = function(x, forward = TRUE, maxgap = Inf, na.rm = FALSE) {
    if (!forward) x = rev(x)           # reverse x twice if carrying backward
    ind = which(!is.na(x))             # get positions of nonmissing values
    if (is.na(x[1]) && !na.rm)         # if it begins with NA
        ind = c(1,ind)                 # add first pos
    rep_times = diff(                  # diffing the indices + length yields how often
        c(ind, length(x) + 1) )          # they need to be repeated
    if (maxgap < Inf) {
        exceed = rep_times - 1 > maxgap  # exceeding maxgap
        if (any(exceed)) {               # any exceed?
            ind = sort(c(ind[exceed] + 1, ind))      # add NA in gaps
            rep_times = diff(c(ind, length(x) + 1) ) # diff again
        }
    }
    x = rep(x[ind], times = rep_times) # repeat the values at these indices
    if (!forward) x = rev(x)           # second reversion
    x
}

আমি আমার ফর্মার প্যাকেজে ফাংশনটিও রেখেছি (কেবল গিথুব)।


2
+1, তবে আমি অনুমান করছি যে আপনি যদি dfএকাধিক কলামের সাথে এটি প্রয়োগ করতে চান তবে এটি প্রতি কলামে লুপ হওয়া দরকার ?
ঝুবার্ব

3
আপনার প্রতিবেদনের জন্য আবারও রুবেনকে ধন্যবাদ। এতক্ষণে বাগটি আর-ফোর্জে স্থির করা হয়েছে। এছাড়াও আমি ওয়ার্কহর্স ফাংশনটি টুইট এবং রফতানি করেছি na.locf0যা এখন আপনার repeat_lastকার্যের সাথে স্কোপ এবং পারফরম্যান্সের অনুরূপ । ক্লুটি ব্যবহার diffনা করে বরং cumsumএড়ানো উচিত ifelse। প্রধান na.locf.defaultফাংশন এখনও কিছুটা ধীর কারণ এটি আরো কিছু চেক এবং হ্যান্ডলগুলি একাধিক কলাম ইত্যাদি নেই
সালে Achim Zeileis

23

একটি data.tableসমাধান:

dt <- data.table(y = c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA))
dt[, y_forward_fill := y[1], .(cumsum(!is.na(y)))]
dt
     y y_forward_fill
 1: NA             NA
 2:  2              2
 3:  2              2
 4: NA              2
 5: NA              2
 6:  3              3
 7: NA              3
 8:  4              4
 9: NA              4
10: NA              4

এই পদ্ধতির পাশাপাশি জিরোও ফরোয়ার্ড পূরণের সাথে কাজ করতে পারে:

dt <- data.table(y = c(0, 2, -2, 0, 0, 3, 0, -4, 0, 0))
dt[, y_forward_fill := y[1], .(cumsum(y != 0))]
dt
     y y_forward_fill
 1:  0              0
 2:  2              2
 3: -2             -2
 4:  0             -2
 5:  0             -2
 6:  3              3
 7:  0              3
 8: -4             -4
 9:  0             -4
10:  0             -4

এই পদ্ধতিটি স্কেল পর্যায়ে ডেটাতে খুব কার্যকর হয়ে ওঠে এবং যেখানে আপনি গ্রুপ (গুলি) দ্বারা ফরোয়ার্ড ফিল করতে চান, যা এর সাথে তুচ্ছ data.table। যুক্তি যুক্ত byহওয়ার আগে কেবল দলে গ্রুপ (গুলি) যুক্ত করুন cumsum

dt <- data.table(group = sample(c('a', 'b'), 20, replace = TRUE), y = sample(c(1:4, rep(NA, 4)), 20 , replace = TRUE))
dt <- dt[order(group)]
dt[, y_forward_fill := y[1], .(group, cumsum(!is.na(y)))]
dt
    group  y y_forward_fill
 1:     a NA             NA
 2:     a NA             NA
 3:     a NA             NA
 4:     a  2              2
 5:     a NA              2
 6:     a  1              1
 7:     a NA              1
 8:     a  3              3
 9:     a NA              3
10:     a NA              3
11:     a  4              4
12:     a NA              4
13:     a  1              1
14:     a  4              4
15:     a NA              4
16:     a  3              3
17:     b  4              4
18:     b NA              4
19:     b NA              4
20:     b  2              2

1
দলগুলি দ্বারা এটি করার ক্ষমতা দুর্দান্ত!
জেসিওয়ং

22

একটি বৃহত ডেটা ভলিউম নিয়ে কাজ করা, আরও দক্ষ হওয়ার জন্য, আমরা ডেটা টেবিল প্যাকেজটি ব্যবহার করতে পারি।

require(data.table)
replaceNaWithLatest <- function(
  dfIn,
  nameColNa = names(dfIn)[1]
){
  dtTest <- data.table(dfIn)
  setnames(dtTest, nameColNa, "colNa")
  dtTest[, segment := cumsum(!is.na(colNa))]
  dtTest[, colNa := colNa[1], by = "segment"]
  dtTest[, segment := NULL]
  setnames(dtTest, "colNa", nameColNa)
  return(dtTest)
}

2
একটি ল্যাপলি যুক্ত করা যায় যাতে এটি সরাসরি এটি একাধিক এনএ কলামগুলিতে প্রয়োগ করতে পারে:replaceNaWithLatest <- function( dfIn, nameColsNa = names(dfIn)[1] ){ dtTest <- data.table(dfIn) invisible(lapply(nameColsNa, function(nameColNa){ setnames(dtTest, nameColNa, "colNa") dtTest[, segment := cumsum(!is.na(colNa))] dtTest[, colNa := colNa[1], by = "segment"] dtTest[, segment := NULL] setnames(dtTest, "colNa", nameColNa) })) return(dtTest) }
এক্সক্লোটেট

প্রথমে আমি এই সমাধানটি দ্বারা উত্তেজিত হয়েছি, তবে এটি আসলে একই জিনিসটি করছে না। প্রশ্নটি অন্য একটির সাথে 1 ডেটা সেট পূরণ করার বিষয়ে। এই উত্তরটি কেবল অনুমানযোগ্য।
হ্যাক-আর

19

আমার টুপিটি এখানে ছোঁড়াচ্ছে:

library(Rcpp)
cppFunction('IntegerVector na_locf(IntegerVector x) {
  int n = x.size();

  for(int i = 0; i<n; i++) {
    if((i > 0) && (x[i] == NA_INTEGER) & (x[i-1] != NA_INTEGER)) {
      x[i] = x[i-1];
    }
  }
  return x;
}')

একটি মৌলিক নমুনা এবং একটি মানদণ্ড সেটআপ করুন:

x <- sample(c(1,2,3,4,NA))

bench_em <- function(x,count = 10) {
  x <- sample(x,count,replace = TRUE)
  print(microbenchmark(
    na_locf(x),
    replace_na_with_last(x),
    na.lomf(x),
    na.locf(x),
    repeat.before(x)
  ), order = "mean", digits = 1)
}

এবং কিছু মানদণ্ড চালান:

bench_em(x,1e6)

Unit: microseconds
                    expr   min    lq  mean median    uq   max neval
              na_locf(x)   697   798   821    814   821 1e+03   100
              na.lomf(x)  3511  4137  5002   4214  4330 1e+04   100
 replace_na_with_last(x)  4482  5224  6473   5342  5801 2e+04   100
        repeat.before(x)  4793  5044  6622   5097  5520 1e+04   100
              na.locf(x) 12017 12658 17076  13545 19193 2e+05   100

শুধু ক্ষেত্রে:

all.equal(
     na_locf(x),
     replace_na_with_last(x),
     na.lomf(x),
     na.locf(x),
     repeat.before(x)
)
[1] TRUE

হালনাগাদ

একটি সংখ্যক ভেক্টরের জন্য, ফাংশনটি কিছুটা পৃথক:

NumericVector na_locf_numeric(NumericVector x) {
  int n = x.size();
  LogicalVector ina = is_na(x);

  for(int i = 1; i<n; i++) {
    if((ina[i] == TRUE) & (ina[i-1] != TRUE)) {
      x[i] = x[i-1];
    }
  }
  return x;
}

15

এটি আমার পক্ষে কাজ করেছে:

  replace_na_with_last<-function(x,a=!is.na(x)){
     x[which(a)[c(1,1:sum(a))][cumsum(a)+1]]
  }


> replace_na_with_last(c(1,NA,NA,NA,3,4,5,NA,5,5,5,NA,NA,NA))

[1] 1 1 1 1 3 4 5 5 5 5 5 5 5 5

> replace_na_with_last(c(NA,"aa",NA,"ccc",NA))

[1] "aa"  "aa"  "aa"  "ccc" "ccc"

গতিও যুক্তিসঙ্গত:

> system.time(replace_na_with_last(sample(c(1,2,3,NA),1e6,replace=TRUE)))


 user  system elapsed 

 0.072   0.000   0.071 

2
শীর্ষস্থানীয় এনএ থাকাকালীন এই ফাংশনটি আপনি যা প্রত্যাশা করেন তা করে না। replace_na_with_last(c(NA,1:4,NA))(অর্থাত তারা নীচের মান দিয়ে পূর্ণ হয়)। এটিও এর ডিফল্ট আচরণ imputeTS::na.locf(x, na.remaining = "rev")
রুবেন

এই ক্ষেত্রে, কিছুটা ভিন্ন পদ্ধতির জন্য একটি ডিফল্ট যুক্ত করা আরও ভাল: replace_na_with_last<-function(x,p=is.na,d=0)c(d,x)[cummax(seq_along(x)*(!p(x)))+1]
নিক ন্যাসুফিস

@ নিকনাসুফিসের উত্তরটি সংক্ষিপ্ত, মিষ্টি, প্যাকেজ নির্ভর নয়, এবং dplyr পাইপগুলির সাথে ভালভাবে কাজ করে!
কিম

14

এই ফাংশন চেষ্টা করুন। এটির জন্য চিড়িয়াখানা প্যাকেজটির প্রয়োজন নেই:

# last observation moved forward
# replaces all NA values with last non-NA values
na.lomf <- function(x) {

    na.lomf.0 <- function(x) {
        non.na.idx <- which(!is.na(x))
        if (is.na(x[1L])) {
            non.na.idx <- c(1L, non.na.idx)
        }
        rep.int(x[non.na.idx], diff(c(non.na.idx, length(x) + 1L)))
    }

    dim.len <- length(dim(x))

    if (dim.len == 0L) {
        na.lomf.0(x)
    } else {
        apply(x, dim.len, na.lomf.0)
    }
}

উদাহরণ:

> # vector
> na.lomf(c(1, NA,2, NA, NA))
[1] 1 1 2 2 2
> 
> # matrix
> na.lomf(matrix(c(1, NA, NA, 2, NA, NA), ncol = 2))
     [,1] [,2]
[1,]    1    2
[2,]    1    2
[3,]    1    2

এটা উন্নত করার জন্য আপনি এই যুক্ত করতে পারেন: if (!anyNA(x)) return(x)
আর্টেম ক্লিভতসভ

13

একটি নেতৃস্থানীয় রয়ে NAএকটি বলি একটি বিট, কিন্তু আমি LOCF করছেন যখন নেতৃস্থানীয় শব্দ খুব পাঠযোগ্য (এবং ভেক্টরকৃত) উপায় খুঁজে না হারিয়েছে:

na.omit(y)[cumsum(!is.na(y))]

কিছুটা কম পঠনযোগ্য পরিবর্তন সাধারণভাবে কাজ করে:

c(NA, na.omit(y))[cumsum(!is.na(y))+1]

পছন্দসই আউটপুট দেয়:

c(NA, 2, 2, 2, 2, 3, 3, 4, 4, 4)


3
এটি বরং মার্জিত। এটি সব ক্ষেত্রে কার্যকর হয় কিনা তা নিশ্চিত না তবে এটি অবশ্যই আমার পক্ষে কাজ করেছে!
এবিটি

12

আপনি উপলব্ধ data.tableফাংশনটি ব্যবহার করতে পারেন ।nafilldata.table >= 1.12.3

library(data.table)
nafill(y, type = "locf")
# [1] NA  2  2  2  2  3  3  4  4  4

যদি আপনার ভেক্টর একটিতে একটি কলাম হয় data.table, আপনি এটির সাথে রেফারেন্সও আপডেট করতে পারেন setnafill:

d <- data.table(x = 1:10, y)
setnafill(d, type = "locf", cols = "y")
d
#      x  y
#  1:  1 NA
#  2:  2  2
#  3:  3  2
#  4:  4  2
#  5:  5  2
#  6:  6  3
#  7:  7  3
#  8:  8  4
#  9:  9  4
# 10: 10  4

আপনার যদি NAকয়েকটি কলামে থাকে ...

d <- data.table(x = c(1, NA, 2), y = c(2, 3, NA), z = c(4, NA, 5))
#     x  y  z
# 1:  1  2  4
# 2: NA  3 NA
# 3:  2 NA  5

... আপনি একবারে রেফারেন্সের মাধ্যমে সেগুলি পূরণ করতে পারেন:

setnafill(d, type = "locf")
d
#    x y z
# 1: 1 2 4
# 2: 1 3 4
# 3: 2 3 5

মনে রাখবেন যে:

কেবলমাত্র ডাবল এবং পূর্ণসংখ্যার ডেটা প্রকারগুলি বর্তমানে [ data.table 1.12.6] সমর্থিত।

কার্যকারিতা সম্ভবত শীঘ্রই বাড়ানো হবে; ওপেন ইস্যু নাফিল, চরিত্র, ফ্যাক্টর এবং অন্যান্য ধরণের জন্য সেটনাফিল দেখুন যেখানে আপনি একটি অস্থায়ী কর্মক্ষেত্রও খুঁজে পান ।


5

পরিপাটি প্যাকেজটি এটি করার একটি সহজ উপায় প্রস্তাব করে:

y = c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA)

# first, transform it into a data.frame

y = as.data.frame(y)
   y
1  NA
2   2
3   2
4  NA
5  NA
6   3
7  NA
8   4
9  NA
10 NA

fill(y, y, .direction = 'down')
    y
1  NA
2   2
3   2
4   2
5   2
6   3
7   3
8   4
9   4
10  4

3

এখানে একগুচ্ছ প্যাকেজ অফার রয়েছে na.locf( NAশেষ পর্যবেক্ষণ পরিচালিত ফরওয়ার্ড) ফাংশন:

  • xts - xts::na.locf
  • zoo - zoo::na.locf
  • imputeTS - imputeTS::na.locf
  • spacetime - spacetime::na.locf

এবং অন্যান্য প্যাকেজগুলির যেখানে এই ফাংশনটির নাম আলাদাভাবে দেওয়া হয়েছে।


2

ব্র্যান্ডন বার্টেলসেনের আরসিপি অবদানগুলি অনুসরণ করছেন। আমার জন্য, নিউমারিকেক্টর সংস্করণটি কাজ করে না: এটি কেবল প্রথম এনএ প্রতিস্থাপন করেছে। এটি কারণ inaফাংশনের শুরুতে ভেক্টরটি কেবল একবার মূল্যায়ন করা হয়।

পরিবর্তে, কোনওটি পূর্ণসংখ্যার পরিবেশনার ফাংশনের মতো সঠিক পন্থা নিতে পারে। নিম্নলিখিত আমার জন্য কাজ করেছে:

library(Rcpp)
cppFunction('NumericVector na_locf_numeric(NumericVector x) {
  R_xlen_t n = x.size();
  for(R_xlen_t i = 0; i<n; i++) {
    if(i > 0 && !R_finite(x[i]) && R_finite(x[i-1])) {
      x[i] = x[i-1];
    }
  }
  return x;
}')

আপনার যদি ক্যারেক্টার وেক্টর সংস্করণ প্রয়োজন হয় তবে একই বেসিক পদ্ধতির কাজ করে:

cppFunction('CharacterVector na_locf_character(CharacterVector x) {
  R_xlen_t n = x.size();
  for(R_xlen_t i = 0; i<n; i++) {
    if(i > 0 && x[i] == NA_STRING && x[i-1] != NA_STRING) {
      x[i] = x[i-1];
    }
  }
  return x;
}')

int n = x.size () এবং (int i = 0; i <n; i ++) এর জন্য ডাবল দ্বারা প্রতিস্থাপন করা উচিত। আর-তে কোনও ভেক্টর সি ++ ইনট আকারের চেয়ে বড় হতে পারে।
stats0007

দেখে মনে হচ্ছে এই ফাংশনটি "R_xlen_t" প্রদান করে। আর যদি দীর্ঘ ভেক্টর সমর্থন দিয়ে সংকলিত হয় তবে এটি ptrdiff_t হিসাবে সংজ্ঞায়িত করা হয়েছে; যদি এটি না হয়, এটি একটি int। সংশোধনীর জন্য ধন্যবাদ!
ইভান কর্টেন্স

1

এখানে @ অ্যাডামোর সমাধানটির একটি পরিবর্তন রয়েছে। এটি দ্রুত চালায় কারণ এটি na.omitফাংশনটিকে বাইপাস করে । এটি NAভেক্টরের মানগুলি yঅগ্রাহ্য করবে (শীর্ষস্থানীয় NAগুলি ব্যতীত )।

   z  <- !is.na(y)                  # indicates the positions of y whose values we do not want to overwrite
   z  <- z | !cumsum(z)             # for leading NA's in y, z will be TRUE, otherwise it will be FALSE where y has a NA and TRUE where y does not have a NA
   y  <- y[z][cumsum(z)]

0

আমি নীচে চেষ্টা করেছি:

nullIdx <- as.array(which(is.na(masterData$RequiredColumn)))
masterData$RequiredColumn[nullIdx] = masterData$RequiredColumn[nullIdx-1]

nullIdx আইডিএক্স নম্বর পায় যেখানে কখনও মাস্টারডাটা $ প্রয়োজনীয় কলামে নুল / এনএ মান হয়। পরবর্তী লাইনে আমরা এটি সম্পর্কিত আইডেক্স -১ মান দিয়ে প্রতিস্থাপন করব, অর্থাত্ প্রতিটি এনইউএল / এনএর আগে শেষ ভাল মান


একাধিক টানা অনুপস্থিত মান থাকলে এটি কাজ করে না - 1 NA NAপরিবর্তিত হয় 1 1 NA। এছাড়াও, আমি মনে করি এটি as.array()অপ্রয়োজনীয়।
গ্রেগোর টমাস

0

এটি আমার পক্ষে কাজ করেছে, যদিও আমি নিশ্চিত নই যে এটি অন্যান্য পরামর্শের চেয়ে বেশি দক্ষ কিনা।

rollForward <- function(x){
  curr <- 0
  for (i in 1:length(x)){
    if (is.na(x[i])){
      x[i] <- curr
    }
    else{
      curr <- x[i]
    }
  }
  return(x)
}

0
fill.NAs <- function(x) {is_na<-is.na(x); x[Reduce(function(i,j) if (is_na[j]) i else j, seq_len(length(x)), accumulate=T)]}

fill.NAs(c(NA, 2, 2, NA, NA, 3, NA, 4, NA, NA))

[1] NA  2  2  2  2  3  3  4  4  4

হ্রাস একটি দুর্দান্ত কার্যকরী প্রোগ্রামিং ধারণা যা অনুরূপ কাজের জন্য দরকারী হতে পারে। দুর্ভাগ্যক্রমে আর এ এটি repeat.beforeউপরের উত্তরের চেয়ে times 70 গুণ কম ধীর ।


0

আমি ব্যক্তিগতভাবে এই ফাংশনটি ব্যবহার করি। আমি জানি না এটি কত দ্রুত বা ধীর। কিন্তু এটি লাইব্রেরি ব্যবহার না করেই তার কাজ করে।

replace_na_with_previous<-function (vector) {
        if (is.na(vector[1])) 
            vector[1] <- na.omit(vector)[1]
        for (i in 1:length(vector)) {
            if ((i - 1) > 0) {
                if (is.na(vector[i])) 
                    vector[i] <- vector[i - 1]
            }
        }
        return(vector)
    }

যদি আপনি এই ফাংশনটি কোনও ডেটাফ্রেমে প্রয়োগ করতে চান, যদি আপনার ডেটাফ্রেমকে ডফ বলা হয় তবে সহজভাবে

df[]<-lapply(df,replace_na_with_previous)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.