2017-05-08 137 views
3

就拿例如:如何根據同一列但不同行上的值更新列中的值?

> set.seed(42) 
> ids <- c("u1", "u2", "u3") 
> groups <- c(rep("A",3), rep("B",3), rep("C",3)) 
> reps <- c(rep("r1",9), rep("r2",9), rep("r3",9)) 
> vals <- rnorm(27, 0, 2) 
> 
> df = data.frame(ids = rep(ids, 9), groups = rep(groups,3), reps = reps, vals = vals) 
> df 
    ids groups reps  vals 
1 u1  A r1 2.7419169 
2 u2  A r1 -1.1293963 
3 u3  A r1 0.7262568 
4 u1  B r1 1.2657252 
5 u2  B r1 0.8085366 
6 u3  B r1 -0.2122490 
7 u1  C r1 3.0230440 
8 u2  C r1 -0.1893181 
9 u3  C r1 4.0368474 
10 u1  A r2 -0.1254282 
11 u2  A r2 2.6097393 
12 u3  A r2 4.5732908 
13 u1  B r2 -2.7777214 
14 u2  B r2 -0.5575775 
15 u3  B r2 -0.2666427 
16 u1  C r2 1.2719008 
17 u2  C r2 -0.5685058 
18 u3  C r2 -5.3129108 
19 u1  A r3 -4.8809339 
20 u2  A r3 2.6402267 
21 u3  A r3 -0.6132772 
22 u1  B r3 -3.5626169 
23 u2  B r3 -0.3438347 
24 u3  B r3 2.4293494 
25 u1  C r3 3.7903869 
26 u2  C r3 -0.8609383 
27 u3  C r3 -0.5145388 

我想要做的就是減去C.r1,C.r2和C.r3值的平均值爲每個ID。這個想法是使用C組作爲其他組的基準。

所以在預期結果而言,對於第一兩行:

  • (U1,A,R1)應修改爲2.74 - 平均(3.02,1.27,3.79)= 0.046

  • 我怎樣才能得到這個在所有行工作均值(-0.18,-0.56,-0.86)= -0.69

-

  • (U2,A,R1)應修改爲-1.23一大盤e(大約1M行)表,其中包含除此處相關的其他列之外的其他幾列?我顯然需要按ids進行分組,但是特別匹配group == C以及val的平均值的值的查找有點棘手。

    > dt <- setDT(df) 
    > dt[groups == "C", cmean := mean(vals), ids] 
    

    給我C組測量每個ID的方式(在多個副本),但我真的不能立即使用這些值,因爲所有其他行已經被過濾掉。我想我可能需要以某種方式連鎖,但我不確定具體如何。

    我會在解決方案有着同樣的興趣與data.tabledplyr

  • 回答

    1

    我們可以做子集化「團體」是「C」,通過「入侵」分組後加入,讓「丘壑」的mean,那麼,我們加入了原始數據集on的「IDS」,從與「Meanvals」第一數據集從第二減去「丘壑」,並指定(:=)到「NEWVALS」

    setDT(df)[df[groups=="C", .(Meanvals = mean(vals)), ids], 
             newvals := vals - Meanvals, on = .(ids)] 
    head(df) 
    
    +0

    它的作品,但我不知道爲什麼:)你能解釋一下也許嗎?在這種情況下,「subsetting」不會返回data.table嗎?如何在同一個數據表索引的''''語句中使用data.table? – posdef

    +0

    @posdef是的,它確實是它的子集,但是當我們通過'ids'將原始數據集加入'on'時,'平均值'爲每個對應的'id'重複自己,這可以被減去。在這裏,我們正在使用連接'X [Y,on =。(分組變量)]' – akrun

    +0

    我明白了,是否可以避免修改原始表'dt'並返回修改後的副本la'dplyr'? – posdef

    1

    一個可能dplyr - 解決方案:

    library(dplyr) 
    df %>% group_by(ids) %>% 
        mutate(mean = mean(vals[groups=="C"]), 
         vals = vals - mean) %>% select(-mean) 
    
    # A tibble: 27 × 4 
         ids groups reps  vals 
        <fctr> <fctr> <fctr>  <dbl> 
    1  u1  A  r1 0.04680632 
    2  u2  A  r1 -0.58980895 
    3  u3  A  r1 1.32312422 
    4  u1  B  r1 -1.42938536 
    5  u2  B  r1 1.34812404 
    
    相關問題