2015-12-02 13 views
5

Już kilka razy zdumiewało mnie to, więc oto gotowe pytanie dla innych, którzy mogą natknąć się na ten sam problem.Wymiana elementu w jednostce sieci wektorowej

Rozważmy tę jednostkę siatka wektor,

a = unit(1:3, c("cm", "in", "npc")) 

Chcę wymienić niektóre elementy z nowymi wartościami. Naturalne podejście byłoby,

a[1] = unit(2,"pt") 
a 
# [1] 2cm 2in 3npc 

Coś poszło nie tak: zmieniono tylko wartość liczbową, a nie jednostkę. Czemu? Co robić?

Edytuj: Jak wskazano w jednej odpowiedzi poniżej, takie jednostki są po prostu wektorami liczbowymi z atrybutami. Jednak ich potomstwo: unit.arithmetic i unit.list powinno być również uważane za rozwiązanie w pełni ogólne (np. W celu dostosowania rozmiarów paneli obiektów ggplot). Rozważ ten wektor jednostkowy,

(b = a + unit(1, "npc")) 
# [1] 1cm+1npc 2in+1npc 3npc+1npc 
# [1] "unit.arithmetic" "unit" 

Teraz zastąpienie konkretnego elementu jest trudniejsze, ponieważ nie jest już atomowe.

Odpowiedz

2

Wygląda na to, że a to po prostu wektor atomowy z pewnymi atrybutami. Tak więc, kiedy używasz a[1] = unit(2,"pt"), nowa funkcja unit tworzy inny wektor atomowy o długości jeden, który zastępuje wartość a[1]. Atrybuty pozostają nietknięte.

Tak, coś w tym wydaje się działać:

a[1] <- 2 
attr(a, 'unit')[1] <- 'pt' 

> a 
[1] 2pt 2in 3npc 
+0

Jednak mam wrażenie, że już to wiesz. – LyzandeR

+0

Byłem w trakcie pisania odpowiedzi, ale utknąłem w pewnym momencie. Twoje podejście jest poprawne, ale obawiam się, że nie jest ono całkowicie ogólne, ponieważ wektory jednostkowe mogą również zawierać bardziej złożone elementy, takie jak unit.arithmetic: 'b = a + unit (1," npc ")'. Będę edytować pytanie. – baptiste

+0

Widzę, gdzie może pójść nie tak z 'unit.arithmetics'. Jeśli powiesz, że metoda [<-' będzie trudna do wdrożenia, nie mam powodu, aby ci nie wierzyć. 'unit.list' wygląda na wystarczająco dobre rozwiązanie tbh. – LyzandeR

3

Po dyskusji z Paulem Murrell (i, zabawnie, ponowne wynalezienie co ja figured out before), problem leży w nieobecności [<- metoda dla jednostek gridowych. Długofalowym rozwiązaniem byłoby wdrożenie tych metod, ale nie jest to trywialne, ponieważ jednostki gridowe pochodzą z rodzeństwem, na przykład unit.arithmetic i unit.list, a ich interakcja może być trudna do zrozumienia.

Łatwiejsza, zorientowana na użytkownika poprawka polega na konwersji takich wektorów jednostek na obiekty unit.list, które odziedziczą metodę dostępową bardziej jak zwykłe listy R. Tej promocji do obiektu unit.list można dokonać przy użyciu nieodportowanej funkcji grid:::unit.list().

a = unit(1:3, c("cm", "in", "npc")) 
b = grid:::unit.list(a) 
is.list(b) # check that indeed this is a list object, thanks @Josh O'Brien 
# [1] TRUE 
# so now we can use standard list methods 
b[[1]] = unit(2,"pt") 
b 
#[1] 2pt 2in 3npc 
+0

proszę wyjaśnić mi, dlaczego prymityw "[<-' teraz robi to, co należy: ja [nie mogę znaleźć metody dla jednostki.list albo: S] (https://github.com/wch/r-source/ blob/b156e3a711967f58131e23c1b1dc1ea90e2f0c43/src/library/grid/R/unit.R) – baptiste

+0

Nie potrzebuje specjalnej metody. To tylko domyślne zachowanie '[<-' po zastosowaniu do listy (i' unit.list' to lista). –

+0

, ale dlaczego jest to lista? (lub jak widzisz, że to jeden). Myślę, że to ma coś wspólnego z is.atomic (?) – baptiste