2015-11-02 1 views
1

У меня есть функция, с которой я хотел бы быть в состоянии вернуть довольно расслабленный набор структур:(s) применяя подмножество (т.е. `[`) для различных списков структур

str1 <- list(
      list(
      key = 123, 
      data = "test" 
     ), 
      list(
      key = 987, 
      data = "test" 
     ) 
     ) 

str2 <- list(
      c(key = 123, data = "test"), 
      c(key = 987, data = "test") 
     ) 

str3 <- list(
      key = 123, 
      data = "test" 
     ) 

str4 <- c(key = 123, data = "test") 

С эти возвращаемые значения я хотел бы иметь возможность фиксировать все ключевые значения в сжатой форме.

Моя попытка поймать все решение было это:

sapply(str1, `[`, "key") 

Однако, это работает только для вложенных структур (str1 & str2). Остальные возвращаются NA.

мне очень интересно, почему я могу это сделать:

str4["key"] 
# 123 
sapply(c(key = 1), `+`, 1) 
# 2 

... но не это?

sapply(c(key = 123), `[`, "key") 
# NA 

Меня не интересует обходной путь, так как я должен понять, где я здесь ошибся.

ответ

1

Чтобы понять разницу между вашими двумя последними строками кода, вы можете сделать:

> sapply(c(key = 123), function(i) browser()) 
Called from: FUN(X[[i]], ...) 
Browse[1]> i 
[1] 123 
Browse[1]> i+1 
[1] 124 
Browse[1]> i['key'] 
[1] NA 

Вы, в основном пытаются извлечь значение по имени на ... unamed вектор.

Чтобы решить проблему, возможный подход мог бы быть:

foo = function(str, key) {l=unlist(str); l[names(l) %in% key]} 

#> foo(str1,'key') 
# key key 
#"123" "987" 
#> foo(str2,'key') 
# key key 
#"123" "987" 
#> foo(str3,'key') 
# key 
#"123" 
#> foo(str4,'key') 
# key 
#"123" 
+0

Это здорово, спасибо! Теперь это кажется очевидным, как всегда, но мне нравится трюк 'browser(), который будет полезен много раз, я уверен. – 17843

+0

это лучший способ отладки и понимания! –