2016-01-13 47 views
0

注意:使用示例數據框進行修改以提高可讀性。刪除數據幀的某些子集,並修改其他子集

假設我有以下數據框df

GRID FLOW NITER tau eta psi 
67  0 87 66001 0.6571 0.9050 0.5947 
68  0 87 67001 0.6571 0.9050 0.5947 
69  0 87 68001 0.6571 0.9050 0.5947 
70  0 87 69001 0.6572 0.9050 0.5947 
71  0 87 70001 0.6571 0.9050 0.5947 
72  0 87 71001 0.6572 0.9050 0.5947 
73  0 87 72001 0.6571 0.9050 0.5947 
74  0 87 73001 0.6571 0.9050 0.5947 
75  0 87 74001 0.6571 0.9050 0.5947 
207 1 87 66001 0.6539 0.9001 0.5886 
208 1 87 67001 0.6539 0.9001 0.5886 
209 1 87 68001 0.6539 0.9001 0.5886 
210 1 87 69001 0.6539 0.9001 0.5886 
277 2 87 66001 0.6573 0.9031 0.5935 
278 2 87 67001 0.6573 0.9031 0.5935 
279 2 87 68001 0.6573 0.9031 0.5935 
280 2 87 69001 0.6573 0.9031 0.5935 
347 3 87 66001 0.6575 0.9020 0.5930 
348 3 87 67001 0.6575 0.9020 0.5930 
349 3 87 68001 0.6575 0.9020 0.5930 
350 3 87 69001 0.6575 0.9020 0.5930 
627 7 87 66001 0.6573 0.9020 0.5929 
628 7 87 67001 0.6573 0.9020 0.5929 
629 7 87 68001 0.6573 0.9020 0.5929 
630 7 87 69001 0.6573 0.9021 0.5929 
631 7 87 70001 0.6573 0.9021 0.5929 
632 7 87 71001 0.6573 0.9021 0.5929 
633 7 87 72001 0.6573 0.9021 0.5929 
634 7 87 73001 0.6573 0.9021 0.5929 
635 7 87 74001 0.6573 0.9021 0.5929 

GRID變量和NITER變量是整數。如您所見,對於GRID(本例中爲1,2和3)的某些值,NITER的最大值爲69001.對於其他GRID(本例中爲0和7)的值,最大值NITER高於69001。對於所有這些組,我需要用NITER < 69001消除觀察結果,並將70000減去其他觀察值的NITER值。我可以用for循環做到這一點,但循環在R中很慢,因此我更喜歡更R風格的解決方案。

+1

假設您可以使用另一個變量'GRID'來區分組(即''GRID'是唯一的)。 'dplyr'應該可以做到。然後你可以'group_by(grid)%>%mutate(itermax = max(NITER))'等等。不需要循環。 – intra

+0

如果你製作一個10到15行和期望輸出的小例子,情況會更好。 – akrun

+0

@intra,非常感謝您的建議。我安裝了你所指的'dplyr'軟件包,並且'需要'它。我收到了一些警告消息,希望不重要。但是,我不知道你使用的命令。我試着執行你的指令,但它不起作用(我猜是因爲'df'沒有被引用)。你能否詳細解釋一下答案?再次感謝。 – DeltaIV

回答

1

dplyr使用鏈接來提高可讀性。如果你習慣使用SQL,你應該發現這個語法非常有用。

良好的手動太:https://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html

因爲我只是猜測你的數據的結構,我只能僞碼的響應。同樣,如果按照GRID進行分組,您就可以瞭解您正在嘗試調整的NITER的「塊」。

df1 <- df %>% 
     group_by(GRID) %>% 
     mutate(itermax=max(NITER), 
       NNITER=ifelse(itermax>69001L, NITER-70000L, NITER), 
       keep=NNITER > 0) %>% 
     filter(keep) %>% 
     select(GRID, FLOW, NNITER, tau, eta, psi) 


> as.data.frame(df1) 
    GRID FLOW NNITER tau eta psi 
1  0 87  1 0.6571 0.9050 0.5947 
2  0 87 1001 0.6572 0.9050 0.5947 
3  0 87 2001 0.6571 0.9050 0.5947 
4  0 87 3001 0.6571 0.9050 0.5947 
5  0 87 4001 0.6571 0.9050 0.5947 
6  1 87 66001 0.6539 0.9001 0.5886 
7  1 87 67001 0.6539 0.9001 0.5886 
8  1 87 68001 0.6539 0.9001 0.5886 
9  1 87 69001 0.6539 0.9001 0.5886 
10 2 87 66001 0.6573 0.9031 0.5935 
11 2 87 67001 0.6573 0.9031 0.5935 
12 2 87 68001 0.6573 0.9031 0.5935 
13 2 87 69001 0.6573 0.9031 0.5935 
14 3 87 66001 0.6575 0.9020 0.5930 
15 3 87 67001 0.6575 0.9020 0.5930 
16 3 87 68001 0.6575 0.9020 0.5930 
17 3 87 69001 0.6575 0.9020 0.5930 
18 7 87  1 0.6573 0.9021 0.5929 
19 7 87 1001 0.6573 0.9021 0.5929 
20 7 87 2001 0.6573 0.9021 0.5929 
21 7 87 3001 0.6573 0.9021 0.5929 
22 7 87 4001 0.6573 0.9021 0.5929 
+0

非常感謝您的回答。我不知道什麼是SQL。我不知道今天能不能做到,但最遲明天我會用一個'df'的樣本來更新這個問題,它比實際的小,但是具有相似的結構。順便說一下,是的,通過'GRID'分組有效地將'NITER'的不同「塊」分開。 – DeltaIV

+0

我設法爲我的問題添加一個'df'樣本。我試圖運行你的指令,但我得到了以下錯誤:'錯誤:不兼容的類型,期望一個數字向量 另外:警告消息: 1:In if(c(69001L,69001L,69001L,69001L,74001L,74001L ,74001L,: 條件長度> 1且僅使用第一個元素 2:In if(c(69001L,69001L,69001L,69001L,74001L,74001L,74001L,: )條件長度> 1且只有第一個元素會被使用' – DeltaIV

+1

已修復。必須在'dplyr'中使用'ifelse'。猜猜我們都學到了東西! – intra