नवीनतम गैर-NA मान के साथ NA की जगह


141

एक data.frame (या data.table) में, मैं निकटतम पिछले गैर-NA मान के साथ NA को "आगे भरना" चाहूंगा। एक सरल उदाहरण, वैक्टर का उपयोग करना (ए के बजाय 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
एक नई विधि के रूप fillमें शुरू की जा रही हैR
सकाम

14
इसके अलावा, में देखें tidyr::fill()
zx8754

जवाबों:


160

आप शायद अपने NA मानों को बदलने के लिए अंतिम अवलोकन को आगे बढ़ाने के लिए चिड़ियाघर पैकेज 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तर्क की आवश्यकता होती है। क्योंकि ज़ू को किनारे के मामलों में कुछ अजीब समस्याएं हैं, जब मैं dplyr + दिनांक का उपयोग करता हूं जिसे मैं डिबग नहीं कर सकता था, मैं आज अपने पुराने फ़ंक्शन को सुधारने के लिए इस पर वापस आया।

मैंने अपने बेहतर फ़ंक्शन और अन्य सभी प्रविष्टियों को यहां बेंचमार्क किया। सुविधाओं के मूल सेट के लिए, tidyr::fillसबसे तेज है जबकि किनारे के मामलों में भी असफल नहीं है। @BrandonBertelsen द्वारा Rcpp प्रविष्टि अभी भी तेज है, लेकिन यह इनपुट के प्रकार के बारे में अनम्य है (उसने गलतफहमी के कारण गलत तरीके से किनारे के मामलों का परीक्षण किया 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कई कॉलमों के साथ लागू करना चाहते हैं तो प्रति कॉलम लूप किया जाना चाहिए ?
Zhubarb

3
@ रूबेन आपकी रिपोर्ट के लिए फिर से धन्यवाद। अब तक बग आर-फोर्ज पर तय हो गया है। इसके अलावा मैंने वर्कहॉर्स फ़ंक्शन को ट्विक किया और निर्यात किया है na.locf0जो अब आपके repeat_lastफ़ंक्शन के दायरे और प्रदर्शन के समान है । सुराग diffसे cumsumबचने के बजाय उपयोग करना थाifelse । मुख्य na.locf.defaultकार्य अभी भी कुछ हद तक धीमा है क्योंकि यह कुछ और जाँच करता है और कई स्तंभों आदि को संभालता है
अचिम ज़ाइलिस

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
समूहों द्वारा ऐसा करने की क्षमता बहुत बढ़िया है!
JCWong

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
एक शिथिल जोड़ा जा सकता है इसलिए यह सीधे इसे कई NA स्तंभों पर लागू कर सकता है: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) }
xclotet

सबसे पहले मैं इस समाधान से उत्साहित था, लेकिन यह वास्तव में एक ही काम नहीं कर रहा है। सवाल दूसरे के साथ 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]
निक नेसुपिस

@NickNassuphis का उत्तर छोटा, मीठा है, पैकेज पर निर्भर नहीं है, और 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] समर्थित हैं।

कार्यक्षमता सबसे अधिक संभावना है जल्द ही विस्तारित होगी; खुले मुद्दे nafill, चरित्र, कारक और अन्य प्रकारों के लिए setnafill देखें , जहां आपको एक अस्थायी समाधान भी मिलता है ।


5

Tidyverse पैकेज ऐसा करने का एक सरल तरीका प्रस्तावित करता है:

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

ब्रैंडन बर्टेल्सन के Rcpp योगदान के बाद। मेरे लिए, न्यूमेरिकवेक्टर संस्करण ने काम नहीं किया: यह केवल पहले एनए को बदल दिया। इसकी वजह है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 ++) को डबल से बदला जाना चाहिए। R में एक वेक्टर c ++ int size से बड़ा हो सकता है।
सांख्यिकी 10007

ऐसा लगता है कि यह फ़ंक्शन "R_xlen_t" देता है। यदि R लंबे वेक्टर समर्थन के साथ संकलित किया जाता है, तो इसे 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 को idx नंबर मिलता है जहाँ कभी मास्टरडेट $ RequiredColumn का Null / NA मान होता है। अगली पंक्ति में हम इसे संबंधित Idx-1 मान के साथ बदलते हैं, अर्थात प्रत्येक NULL / NA से पहले अंतिम अच्छा मूल्य


यह काम नहीं करता है अगर वहाँ लगातार कई लापता मूल्य हैं - 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

कम करना एक अच्छा कार्यात्मक प्रोग्रामिंग अवधारणा है जो समान कार्यों के लिए उपयोगी हो सकता है। दुर्भाग्य से R में यह repeat.beforeऊपर के उत्तर की तुलना में ~ 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)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.