2015-07-10 1 views
2

У меня есть два списка, один из которых содержит различную длину символьных значений (dat), а другой с одним числовым значением в каждом элементе (delete_n).Удаление определенных элементов в списке на основе номеров в другом списке в R

dat <- list(c("Apple", "Pear"), c("Red", "Blue", "Green"), c("Toyota", "Mazda")) 
delete_n <- list(0, 2, 1) 

элементов в "delete_n" паре с элементами "DAT" (delete_n [1] идет с DAT [1], и так далее). Номера «delete_n» (0,2,1) говорят мне, сколько конкретных элементов списка в каждом элементе, который мне нужно удалить, с конца каждой строки.

Основываясь на примере, я ищу решение, которое удалит 0 элементов из dat [1], удалит «Blue» и «Green» из dat [2] и «Mazda» из dat [3].

Я пробовал сначала сопоставить номера элементов, а затем идентифицировать индекс списка элементов по вариациям ниже, без каких-либо успехов. mapply может быть более уместным, но опять же я не понимаю, как написать часть функции().

lapply(seq_along(dat), function(x) { 
    sapply(seq_along(delete_n), function(y) { 
     x[y] 
    }) 
}) 

ответ

5
mapply(function (x, n) { 
    # x is an element of dat; n is an element of delete_n 
    x[seq_len(length(x)-n)] 
}, dat, delete_n) 

Пояснение:

mapply применяет функцию к каждому элементу dat и delete_n, взятые вместе (так что все первые элементы, все элементы второго, и т.д.).

seq_len(i) делает вектор 1:i, так seq_len(length(x)-n) выбирает все, но последние n элементы x.

+1

Вариации на тему: 'Map (функция (г, п), если (п == 0) d еще голова (d, -n), Дат, delete_n)' – thelatemail

+0

@thelatemail я изначально пошел с 'head (d, -n)', но если n = 0, то он терпит неудачу (возвращает 0-length). –

+0

Использование отрицательных нулей в 'tail' и' head' не работало так, как я ожидал. Я не думаю, что это может читать наши мысли с '(-0) == 0 # [1] TRUE' –

3

Просто потому, что я не мог позволить этому идти без head работы:
Если изменить delete_n к вектору c(0,2,1) (который может быть легко, так как есть только одно значение для каждого соответствующего dat элемента списка), вы можете делать:

Map(head, dat, n=-replace(delete_n, delete_n==0, -Inf)) 
3

мне понравился mapply подход, но это было то, что казалось естественным для меня (после неудачи с отрицательными нулями в любом случае).

mapply(head, dat, sapply(dat, length)- unlist(delete_n)) 
#------- 
[[1]] 
[1] "Apple" "Pear" 

[[2]] 
[1] "Red" 

[[3]] 
[1] "Toyota" 
+0

В обновленном R вы можете заменить 'sapply (dat, length)' на 'lengths (dat)' тоже. – thelatemail