2013-01-16 15 views
12

से एनएएस के ब्लॉक कैसे छोड़ना चाहिए मेरे पास एक बहु स्तंभ कुंजी के साथ एक बड़ा आर data.table है, जहां कुछ मूल्य कॉलम में कुछ NA शामिल हैं। मैं उन समूहों को हटाना चाहता हूं जो पूरी तरह से एक या अधिक मूल्य कॉलम में NA हैं, लेकिन पूरे समूह को अन्यथा रखें। कुंजी के प्रत्येक कॉलम के लिए इसे दोहराएं।मुझे आर डेटाटेबल

  • श्रृंखला:: एक, डी, ई, एच और एल
  • पहचान:

    library(data.table) 
    DT = data.table(
        Series = rep(letters[1:12], each = 3), 
        Id = 1:12, 
        Value1 = c(1:3, NA, 5:9, rep(NA,3), 1:3, NA, 5:9, rep(NA,3), 1:3, NA, 5:9, rep(NA,3)), 
        Value2 = c(rep(NA,3), 1:4, NA, 6:9, rep(NA,3), 1:9, 1:9, rep(NA,3))) 
    DT 
        Series Id Value1 Value2 
    1:  a 1  1  NA 
    2:  a 2  2  NA 
    3:  a 3  3  NA 
    4:  b 4  NA  1 
    5:  b 5  5  2 
    6:  b 6  6  3 
    7:  c 7  7  4 
    8:  c 8  8  NA 
    9:  c 9  9  6 
    10:  d 10  NA  7 
    11:  d 11  NA  8 
    12:  d 12  NA  9 
    13:  e 1  1  NA 
    14:  e 2  2  NA 
    15:  e 3  3  NA 
    16:  f 4  NA  1 
    17:  f 5  5  2 
    18:  f 6  6  3 
    19:  g 7  7  4 
    20:  g 8  8  5 
    21:  g 9  9  6 
    22:  h 10  NA  7 
    23:  h 11  NA  8 
    24:  h 12  NA  9 
    25:  i 1  1  1 
    26:  i 2  2  2 
    27:  i 3  3  3 
    28:  j 4  NA  4 
    29:  j 5  5  5 
    30:  j 6  6  6 
    31:  k 7  7  7 
    32:  k 8  8  8 
    33:  k 9  9  9 
    34:  l 10  NA  NA 
    35:  l 11  NA  NA 
    36:  l 12  NA  NA 
        Series Id Value1 Value2 
    

    तो मैं छोड़ने के लिए करना चाहते हैं:

    एक सरल उदाहरण के लिए 4, 10,

    : 11 और 12

सही परिणाम की तरह दिखना चाहिए

Series Id Value1 Value2 
1:  b 5  5  2 
2:  b 6  6  3 
3:  c 7  7  4 
4:  c 8  8  NA 
5:  c 9  9  6 
6:  f 5  5  2 
7:  f 6  6  3 
8:  g 7  7  4 
9:  g 8  8  5 
10:  g 9  9  6 
11:  i 1  1  1 
12:  i 2  2  2 
13:  i 3  3  3 
14:  j 5  5  5 
15:  j 6  6  6 
16:  k 7  7  7 
17:  k 8  8  8 
18:  k 9  9  9 
    Series Id Value1 Value2 

क्या मैं अब तक कामयाब रहे:

मैं श्रृंखला है कि इस तरह मान 1 के लिए लागू नहीं कर रहे हैं पा सकते हैं:

DT[, sum(1-is.na(Value1)) == 0, by = Series][V1 == TRUE] 

और मैं भी कर सकता है

setkey(DT, Series) 
DT = DT[DT[, sum(1-is.na(Value)) == 0, by = Series][V1 != TRUE]] 

लेकिन अब मैं अंतिम तालिका में दिखाई देने वाले वी 1 के साथ समाप्त होता हूं।

+2

क्यों न सिर्फ 'na.omit (डीटी)' के साथ एक स्तंभ मान है कि छोड़ देंगे? – Justin

+0

'na.omit' सिर्फ सभी एनएएस को हटा रहा है। मैं केवल तब हटाना चाहता हूं जब संपूर्ण "ब्लॉक" NA हो। तो उदाहरण में, एम या जेड के लिए कोई मूल्य नहीं है, इसलिए उन्हें छोड़ दिया जाना चाहिए, लेकिन मैं सीरीज बी – Corone

+0

में दो एनएएस ड्रॉप नहीं करना चाहता हूं तो @ अरुण का आपका जवाब है, लेकिन आपको ' .logical'। – Justin

उत्तर

9

आप इन प्रविष्टियों को प्राप्त करने के लिए ऐसा कर सकते हैं जहां सभी ValueNA नहीं:

setkey(DT, "Series") 
DT[, .SD[(!all(is.na(Value)))], by=Series] 

कोष्ठक के आसपास !all वाक्य रचना जो मैथ्यू पर गौर करेंगे (टिप्पणी देखें) नहीं-में शामिल होने से बचने के लिए की जरूरत है। इस रूप में एक ही:

नई स्पष्ट सवाल का जवाब देने पर
DT[, .SD[as.logical(!all(is.na(Value)))], by=Series] 

भवन:

allNA = function(x) all(is.na(x))  # define helper function 
for (i in c("Id","Series")) 
    DT = DT[, if (!any(sapply(.SD,allNA))) .SD else NULL, by=i] 
DT 
    Series Id Value1 Value2 
1:  i 1  1  1 
2:  i 2  2  2 
3:  i 3  3  3 
4:  b 5  5  2 
5:  b 6  6  3 
6:  f 5  5  2 
7:  f 6  6  3 
8:  j 5  5  5 
9:  j 6  6  6 
10:  c 7  7  4 
11:  c 8  8  NA 
12:  c 9  9  6 
13:  g 7  7  4 
14:  g 8  8  5 
15:  g 9  9  6 
16:  k 7  7  7 
17:  k 8  8  8 
18:  k 9  9  9 

क्रम परिवर्तन है कि, हालांकि। तो परिणाम का अनुरोध ठीक नहीं है। निम्नलिखित आदेश रखता है और तेजी से भी होना चाहिए।

# starting fresh from original DT in question again 
DT[,drop:=FALSE] 
for (i in c("Series","Id")) 
    DT[,drop:=drop|any(sapply(.SD,allNA)),by=i] 
DT[(!drop)][,drop:=NULL][] 
    Series Id Value1 Value2 
1:  b 5  5  2 
2:  b 6  6  3 
3:  c 7  7  4 
4:  c 8  8  NA 
5:  c 9  9  6 
6:  f 5  5  2 
7:  f 6  6  3 
8:  g 7  7  4 
9:  g 8  8  5 
10:  g 9  9  6 
11:  i 1  1  1 
12:  i 2  2  2 
13:  i 3  3  3 
14:  j 5  5  5 
15:  j 6  6  6 
16:  k 7  7  7 
17:  k 8  8  8 
18:  k 9  9  9 
+0

किसी कारण से, 'एसडी [! सब (is.na (वैल्यू))]' काम नहीं करता है। – Arun

+0

+1 '!' = शामिल नहीं है, लेकिन मुझे यकीन नहीं है कि यह क्यों काम नहीं करेगा (तार्किक के लिए कोई फर्क नहीं पड़ता है, शायद रीसाइक्लिंग के साथ संयोजन में शामिल होने की संभावना हो सकती है) –

+1

ठीक है, अब मै समझता हुँ। 'एसडी [(! सब (is.na (मूल्य)))]' (paranthesis के साथ) काम करता है! – Arun

10

complete.cases फ़ंक्शन का उपयोग करने के बारे में क्या?

DT[complete.cases(DT),] 

यह पंक्तियाँ एनए

> DT[complete.cases(DT),] 
    Series Id Value1 Value2 
1:  b 4  4  1 
2:  b 5  5  2 
3:  b 6  6  3 
4:  c 7  7  4 
5:  c 8  8  5 
6:  c 9  9  6 
7:  f 4  4  1 
8:  f 5  5  2 
9:  f 6  6  3 
10:  g 7  7  4 
11:  g 8  8  5 
12:  g 9  9  6 
13:  j 4  4  1 
14:  j 5  5  2 
15:  j 6  6  3 
16:  k 7  7  4 
17:  k 8  8  5 
18:  k 9  9  6 
+0

अच्छा काम, जानने के लिए उपयोगी है, लेकिन मुझे "notempty.cases" फ़ंक्शन चाहिए - केवल उन कॉलम को छोड़ दें जो एक कॉलम के लिए पूरी तरह खाली हैं, और अन्य NAs को – Corone

+4

ठीक छोड़ दें, तो आपको डेटासेट उदाहरण बदलना चाहिए, क्योंकि एनए वैल्यू वाले सभी वेरिएबल में एक ही अक्षर की 3 पंक्तियों के लिए एनए मान हैं (वैल्यू 1 और वैल्यू 2 में) –

+0

अच्छा बिंदु, मैंने इसे दिखाने के लिए दो अतिरिक्त एनएएस शामिल किए हैं – Corone