2015-09-17 6 views
7

के साथ सामान्य मानों के आधार पर डेटा.फ्रेम से पंक्तियां निकालें, मैं संख्यात्मक अनुक्रमों की सूची के आधार पर डेटा.फ्रेम से पंक्तियों को फ़िल्टर करने का एक आसान तरीका ढूंढ रहा हूं।किसी सूची

यहाँ एक उदाहरण है:

मेरे प्रारंभिक डेटा फ्रेम:

data <- data.frame(x=c(0,1,2,0,1,2,3,4,5,12,2,0,10,11,12,13),y="other_data") 

मेरी सूची:

list1 <- list(1:5,10:13) 

मेरा लक्ष्य "डाटा" जो वास्तव में होता है से केवल पंक्तियों रखना है "डेटा" के "एक्स" कॉलम में "list1" के समान संख्यात्मक अनुक्रम। तो उत्पादन data.frame होना चाहिए:

finaldata <- data.frame(x=c(1:5,10:13),y="other_data") 

ऐसा करने के लिए कोई भी विचार?

+0

क्या है वांछित आउटपुट यदि स्तंभ 'y' 'सी (" अन्य_डेटा "," डेटा ", प्रतिनिधि (" अन्य_डेटा ", 14) है? –

+0

कृपया 'डेटा <- data.frame (x = c (0,1,2,0,1,2,3,4,5,12,2,0,10,11,12,13), y = पत्र [1:16]) 'उदाहरण के रूप में और अपेक्षित परिणाम दिखाएं। – Roland

उत्तर

2

मैं एक दृश्य के लिए सबसेट के लिए कस्टम समारोह के साथ शुरू किया, तो यह lapply साथ विस्तार करने के लिए आसान है।

#function that takes sequence and a vector 
#and returns indices of vector that have complete sequence 
get_row_indices<- function(sequence,v){ 
    #get run lengths of whether vector is in sequence 
    rle_d <- rle(v %in% sequence) 
    #test if it's complete, so both v in sequence and length of 
    #matches is length of sequence 
    select <- rep(length(sequence)==rle_d$lengths &rle_d$values,rle_d$lengths) 

    return(select) 

} 


#add row ID to data to show selection 
data$row_id <- 1:nrow(data) 
res <- do.call(rbind,lapply(list1,function(x){ 
    return(data[get_row_indices(sequence=x,v=data$x),]) 
})) 

res 

> res 
    x   y row_id 
5 1 other_data  5 
6 2 other_data  6 
7 3 other_data  7 
8 4 other_data  8 
9 5 other_data  9 
13 10 other_data  13 
14 11 other_data  14 
15 12 other_data  15 
16 13 other_data  16 
+0

हेरोका की मदद करने के लिए धन्यवाद! आपका कस्टम फ़ंक्शन ठीक काम करता है :) – jeff6868

1

क्यों zoo से rollapply का उपयोग नहीं:

library(zoo) 

ind = lapply(list1, function(x) { 
    n = length(x) 
    which(rollapply(data$x, n, function(y) all(y==x))) + 0:(n-1) 
}) 

data[unlist(ind),] 
#x   y 
#5 1 other_data 
#6 2 other_data 
#7 3 other_data 
#8 4 other_data 
#9 5 other_data 
#13 10 other_data 
#14 11 other_data 
#15 12 other_data 
#16 13 other_data 
+0

मुझे पता है कि इस तरह की धन्यवाद टिप्पणी निराश है, लेकिन मैं थोड़ी देर के लिए रोलप्ली के साथ इसे बनाने के तरीके पर संघर्ष कर रहा था, इसलिए इसके लिए धन्यवाद – Tensibai

+0

एनपी मैंने अज्ञात (मेरे दृष्टिकोण से) फ़ंक्शन के साथ-साथ अन्य से बहुत कुछ सीखा ! –

0

समारोह match2 प्रत्येक x मूल्य और यह जांच और n लंबाई का एक वेक्टर के खिलाफ अगले n मूल्यों के माध्यम से चला जाता है। फिर अनुक्रमण के लिए अनुक्रम बनाने के लिए Reduce का उपयोग करता है।

match2 <- function(vec) { 
    start <- which(sapply(1:nrow(data), function(i) all(data$x[i:(i+length(vec)-1)] == vec))) 
    Reduce(':', c(start,start+length(vec)-1)) 
} 
इस के साथ

, हम प्रत्येक list1 के लिए प्रक्रिया को दोहराने के लिए एक लागू फ़ंक्शन का उपयोग कर सकते हैं।

s <- sapply(list1, match2) 
data[unlist(s),] 
#  x   y 
# 5 1 other_data 
# 6 2 other_data 
# 7 3 other_data 
# 8 4 other_data 
# 9 5 other_data 
# 13 10 other_data 
# 14 11 other_data 
# 15 12 other_data 
# 16 13 other_data 
1
extract_fun <- function(x, dat){ 
    # Index where the sequences start 
    ind <- which(dat == x[1]) 
    # Indexes (within dat) where the sequence should be 
    ind_seq <- lapply(ind, seq, length.out = length(x)) 
    # Extract the values from dat at the position 
    dat_val <- mapply(`[`, list(dat), ind_seq) 
    # Check if values within dat == those in list1 
    i <- which(as.logical(apply(dat_val, 2, all.equal, x))) # which one is equal? 
    # Return the correct indices 
    ind_seq[[i]] 
} 

list1 में आइटम प्रति सूचकांक प्राप्त करें और उन्हें जरूरत सूचकांक

गठबंधन
all_ind <- do.call(c, lapply(list1, extract_fun, data$x)) 
data[all_ind,] 

परिणाम:

x   y 
5 1 other_data 
6 2 other_data 
7 3 other_data 
8 4 other_data 
9 5 other_data 
13 10 other_data 
14 11 other_data 
15 12 other_data 
16 13 other_data 
संबंधित मुद्दे