2014-10-27 170 views
1

這裏有一個小代碼來說明我的問題:分配矢量另一個向量

x <- 1:10 
# > x 
# [1] 1 2 3 4 5 6 7 8 9 10 

y <- rep(letters[1:2], 5) 
# > y 
# [1] "a" "b" "a" "b" "a" "b" "a" "b" "a" "b" 

z <- rep(c(5,4), 5) 
# > z 
# [1] 5 4 5 4 5 4 5 4 5 4 

現在,這取決於在我發出接下來的兩個命令其爲了我得到不同的subassignments:

  • x第一個,y第二個:

    x[(x == 2) & (y != "a") & (z == 4)] <- "a" 
    # > x 
    # [1] "1" "a" "3" "4" "5" "6" "7" "8" "9" "10" 
    
    y[(x == 2) & (y != "a") & (z == 4)] <- "a" 
    # > y 
    # [1] "a" "b" "a" "b" "a" "b" "a" "b" "a" "b" 
    
  • y第一,x秒:

    y[(x == 2) & (y != "a") & (z == 4)] <- "a" 
        # > y 
        # [1] "a" "a" "a" "b" "a" "b" "a" "b" "a" "b" 
    
        x[(x == 2) & (y != "a") & (z == 4)] <- "a" 
        # > x 
        # [1] "1" "2" "3" "4" "5" "6" "7" "8" "9" "10" 
    

第二向量的分配取決於在前面的向量進行分配。因此,在第二項任務中,我需要確保我的相關指數仍可用於第二次分配。我的第一個想法是:

x[ind <- ((x == 2) & (y != "a") & (z == 4))] <- "a" 
y[ind] <- "a" 
rm(ind) 

我想避免一個單獨的調用來完成給定的,我可能會做了很多本該ind矢量的分配。這仍然會被認爲是R的良好編碼,還是會導致我沒有想到的任何迂迴行爲?

+0

如果要更改的'x'和'y'的元素索引相同,則您的想法有效。此外,你避免了重複的計算(你正在調用兩次'(x == 2)&(y!=「a」)&(z == 4)')。一步一步做,你在'y'之前改變'x',這可能會影響你想改變的'y'元素的計算。 – nicola 2014-10-27 11:07:28

+0

在你的情況下,我會嘗試創建2個不同的向量,如xx和yy,並對它們做如下操作:''yy [(x == 2)&(y!=「a」)&(z == 4)] < - 「a」'',所以你不會改變條件 – 2014-10-27 11:10:26

+0

我剛剛更新了這個問題,強調我想要索引可用,並且我想以清晰的方式做到這一點,但同時避免獨立呼叫做'ind'向量的分配。在'R'中,這仍然被認爲是好的編碼。 – 2014-10-27 11:12:58

回答

3

你的解決方案看起來很好。不過,我仍然認爲你的代碼有點不好。考慮您的第一個項目符號:

x[(x == 2) & (y != "a") & (z == 4)] <- "a" 
y[(x == 2) & (y != "a") & (z == 4)] <- "a" 

在1號線,你因爲你分配"a"TRUE指數或許不是,如果沒有指數TRUEnumeric變量x轉換爲character。因此你的輸出類型不是很清楚。這是不好的做法,可能會導致下游的各種問題。你應該呆在類型中。

這也意味着上述第二行中的x == 2有些不清楚,儘管R正確地解釋了比較。然而,再次,它可能導致一個更復雜的例子中的問題。但是,您的應用程序中可能沒有這些類型的問題。

+0

我應該使用'identical()'而不是'z == 4'和'x == 2'嗎? – 2014-10-27 11:22:53

+0

如果我有不同類別的向量('factor','numeric','integer','character'),我該如何保持類型? – 2014-10-27 11:24:58

+0

@ lord.garbage不,因爲檢查對象是否相同。考慮'w < - 1:3;相同(w,2)'產生錯誤。 – 2014-10-27 11:26:34