#r
#r
Вопрос:
Допустим, у меня есть следующие data.frames и список
# data frames
df1 = data.frame(y1 = c(1:5), y2 = c(8:12))
df2 = data.frame(y1 = c(5:8), y2 = c(9:12))
df3 = data.frame(y1 = c(5:8), y2 = c(9:12))
df4 = data.frame(y1 = c(11:15), y2 = c(16:20))
# list of data.frames
my.list <- list(df1, df2, df3, df4)
Я хочу найти позицию df1
в списке, и я попробовал это, но получил NA
. Я тоже пытался ==
, но получаю ошибку.
match(df1, my.list)
# [1] NA NA
Но когда я делаю это, я получаю результаты
list14 = my.list[c(1,4)]
match(list14, my.list)
# [1] 1 4
Я считаю, что это как-то связано []
[[]]
с обозначением vs в списке. В конечном итоге я хочу сделать что-то вроде
for (i in list14) {
cbind(list14, "indexPositionOf_list14_in_my.list")
}
где indexPositionOf_list14_in_my.list
находится позиция индекса соответствующего data.frame в list14
in my.list
.
Ожидаемый результат из for
цикла
[[1]]
y1 y2 id
1 1 8 1
2 2 9 1
3 3 10 1
4 4 11 1
5 5 12 1
[[2]]
y1 y2 id
1 11 16 4
2 12 17 4
3 13 18 4
4 14 19 4
5 15 20 4
Комментарии:
1. Вы можете сделать
match(list(df1), my.list)
, но если вы просто хотите добавить индекс к каждому элементу в списке, тогда вы можете сделатьmapply(cbind, my.list, id=seq_along(my.list), SIMPLIFY = FALSE)
2. Ах, это было легко для одной вещи. Спасибо. Теперь предположим, что я хочу сделать то же самое для
df2
ordf3
, это дает мне только позицию 2, но должно давать 2 и 3, потомуdf2 = df3
что . Как с этим справиться?3.
match()
возвращает только первое совпадение для каждого элемента, который вы пытаетесь сопоставить в таблице. Если вам нужно вернуть несколько значений, то эта функция не для вас.match()
4. Хорошо, like
%in%
дает вам все совпадения, есть ли что-нибудь подобное для списков, кромеmatch
тех, о которых вы знаете?5. Помогает ли это вообще?
which(sapply(my.list,function(x) isTRUE(all.equal(x,df2))))
Ответ №1:
Вы можете использовать duplicated
и mapply
:
mapply(cbind, my.list, id=seq_along(my.list), SIMPLIFY = FALSE)[duplicated(my.list) | duplicated(my.list, fromLast = TRUE)]
[[1]]
y1 y2 id
1 5 9 2
2 6 10 2
3 7 11 2
4 8 12 2
[[2]]
y1 y2 id
1 5 9 3
2 6 10 3
3 7 11 3
4 8 12 3
Тест
library(rbenchmark)
benchmark("baseR" = {
mapply(cbind, my.list, id=seq_along(my.list), SIMPLIFY = FALSE)[duplicated(my.list) | duplicated(my.list, fromLast = TRUE)]
},
"map" = {
mapply(cbind, my.list, id=seq_along(my.list), SIMPLIFY = FALSE) %>%
map(., inner_join, df3) %>%
map(., compact) %>%
compact()
},
replications = 1000,
columns = c("test", "replications", "elapsed",
"relative", "user.self", "sys.self"))
test replications elapsed relative user.self
1 baseR 1000 0.37 1.000 0.38
2 map 1000 4.82 13.027 4.80
sys.self
1 0.00
2 0.02
Ответ №2:
может быть, что-то вроде этого?
my.list<- mapply(cbind, my.list, id=seq_along(my.list), SIMPLIFY = FALSE)
my.list %>%
map(., inner_join, df3) %>%
map(., compact) %>%
compact()
#> Joining, by = c("y1", "y2")
#> Joining, by = c("y1", "y2")
#> Joining, by = c("y1", "y2")
#> Joining, by = c("y1", "y2")
#> [[1]]
#> y1 y2 id
#> 1 5 9 2
#> 2 6 10 2
#> 3 7 11 2
#> 4 8 12 2
#>
#> [[2]]
#> y1 y2 id
#> 1 5 9 3
#> 2 6 10 3
#> 3 7 11 3
#> 4 8 12 3