2012-03-01 55 views
-4

兩個數據幀的列我有一個數據幀,例如:交織Ñ中的R

lat lon var01 var02 var03 var04 var11 var12 var13 var14 ... 

,另一個這樣的:

lat lon var05 var15 var25 ... 

的所需的輸出是:

lat lon var01 var02 var03 var04 var05 var11 var12 var13 var14 var15 ... 

我認爲在R中這很容易,但是到目前爲止我還沒有找到任何方法。我也接受其他語言如bash的解決方案。我也想只有幾行代碼,我知道如何用循環等來做到這一點。

在此先感謝

編輯:以下解決方案要求列的名稱正確。想象一下以下情況:

d1 <- data.frame(lat = 1:10, lon = 1:10, V11 = runif(10), V12 = rnorm(10), V21 = runif(10), V22 = rnorm(10)) 
d2 <- data.frame(lat = 1:10, lon = 1:10, A13 = runif(10), A23 = rnorm(10)) 
res <- merge(d1, d2, sort = FALSE) 
res <- res[, c(1:2, order(colnames(res[, -(1:2)])) + 2)] 

輸出是

lat lon  A13  A23  V11  V12  V21  V22 
10 10 0.21269952 0.2670988 0.87532133 -0.6887557 0.60493329 -0.1350546 
    1 1 0.61464497 -0.5686687 0.91287592 -0.4149946 0.23962942 0.3981059 
    2 2 0.55715954 -0.1351786 0.29360337 -0.3942900 0.05893438 -0.6120264 
    3 3 0.32877732 1.1780870 0.45906573 -0.0593134 0.64228826 0.3411197 
    4 4 0.45313145 -1.5235668 0.33239467 1.1000254 0.87626921 -1.1293631 
    5 5 0.50044097 0.5939462 0.65087047 0.7631757 0.77891468 1.4330237 
    6 6 0.18086636 0.3329504 0.25801678 -0.1645236 0.79730883 1.9803999 
    7 7 0.52963060 1.0630998 0.47854525 -0.2533617 0.45527445 -0.3672215 
    8 8 0.07527575 -0.3041839 0.76631067 0.6969634 0.41008408 -1.0441346 
    9 9 0.27775593 0.3700188 0.08424691 0.5566632 0.81087024 0.5697196 

和所需的輸出是:

lat lon V11 V12 A13 V21 V22 A13 
+0

目前尚不清楚你的問題是什麼。你想知道如何合併兩個數據框?看起來不像,因爲你的問題使用了一個「合併」的例子。你只是想改變列的順序?看起來也不像,因爲你的問題已經使用了一個例子。 – Andrie 2012-03-01 11:33:32

+0

我想合併兩個數據幀,但這裏的訣竅是它們具有「組」,使得結果應該像數據集1組1數據集2組1數據集1組2數據集2組2等等 – skd 2012-03-01 11:36:41

+0

什麼是組和數據集的定義? – Andrie 2012-03-01 11:38:18

回答

4

merge()是這份工作的合適工具。這裏有一個例子:

set.seed(1) 
d1 <- data.frame(lat = 1:10, lon = 1:10, V2 = runif(10), V4 = rnorm(10)) 
d2 <- data.frame(lat = 1:10, lon = 1:10, V1 = runif(10), V3 = rnorm(10)) 

## merge the data using `lat` and `lon` 
res <- merge(d1, d2, sort = FALSE) ## `sort = FALSE` stops R reordering rows 

## get columns in right order 
res <- res[, c(1:2, order(colnames(res[, -(1:2)])) + 2)] 

其中給出:根據修訂後的Q

> res 
    lat lon  V1   V2   V3   V4 
1 1 1 0.4820801 0.26550866 0.91897737 -0.8204684 
2 2 2 0.5995658 0.37212390 0.78213630 0.4874291 
3 3 3 0.4935413 0.57285336 0.07456498 0.7383247 
4 4 4 0.1862176 0.90820779 -1.98935170 0.5757814 
5 5 5 0.8273733 0.20168193 0.61982575 -0.3053884 
6 6 6 0.6684667 0.89838968 -0.05612874 1.5117812 
7 7 7 0.7942399 0.94467527 -0.15579551 0.3898432 
8 8 8 0.1079436 0.66079779 -1.47075238 -0.6212406 
9 9 9 0.7237109 0.62911404 -0.47815006 -2.2146999 
10 10 10 0.4112744 0.06178627 0.41794156 1.1249309 

更新:

## dummy data 
set.seed(1) 
df3 <- data.frame(matrix(runif(60), ncol = 6)) 
names(df3) <- paste("df3Var", 1:6, sep = "") 
df3 <- cbind.data.frame(lat = 1:10, lon = 1:10, df3) 
df4 <- data.frame(matrix(runif(30), ncol = 3)) 
names(df4) <- paste("df4Var", 1:3, sep = "") 
df4 <- cbind.data.frame(lat = 1:10, lon = 1:10, df4) 

## merge 
res2 <- merge(df3, df4, sort = FALSE) 

這給:

> head(res2) 
    lat lon df3Var1 df3Var2 df3Var3 df3Var4 df3Var5 df3Var6 
1 1 1 0.2655087 0.2059746 0.9347052 0.4820801 0.8209463 0.47761962 
2 2 2 0.3721239 0.1765568 0.2121425 0.5995658 0.6470602 0.86120948 
3 3 3 0.5728534 0.6870228 0.6516738 0.4935413 0.7829328 0.43809711 
4 4 4 0.9082078 0.3841037 0.1255551 0.1862176 0.5530363 0.24479728 
5 5 5 0.2016819 0.7698414 0.2672207 0.8273733 0.5297196 0.07067905 
6 6 6 0.8983897 0.4976992 0.3861141 0.6684667 0.7893562 0.09946616 
    df4Var1 df4Var2 df4Var3 
1 0.9128759 0.3390729 0.4346595 
2 0.2936034 0.8394404 0.7125147 
3 0.4590657 0.3466835 0.3999944 
4 0.3323947 0.3337749 0.3253522 
5 0.6508705 0.4763512 0.7570871 
6 0.2580168 0.8921983 0.2026923 
> names(res2) 
[1] "lat"  "lon"  "df3Var1" "df3Var2" "df3Var3" "df3Var4" "df3Var5" 
[8] "df3Var6" "df4Var1" "df4Var2" "df4Var3" 

好了,現在注意訂購。假設我們想從df3中抽取兩個變量組中的變量,其中1個變量來自df4,並且在df3df4的每個變量內,變量在它們自己內部的順序是正確的。爲此,我們需要創建一個索引向量ord那就是:

> ord 
[1] 1 2 7 3 4 8 5 6 9 

,我們再加入2太(覆蓋在合併後的數據幀中的latlon列)

> ord + 2 
[1] 3 4 9 5 6 10 7 8 11 

一旦你有序列,我們只需要一種方法來使用R的向量化工具和一點點數學來產生我們想要的序列。我分兩個階段建立指數; i)首先我計算合併數據幀的列(1:6) + 2應該在ord的位置,然後ii)用第二個數據幀的列的合併數據幀中的索引填充剩餘空格。

ord <- numeric(length = sum(ncol(df3), ncol(df4)) - 4) 
ngrps <- 3 
ningrps <- 2 
## i) 
want <- rep(seq_len(ningrps), ngrps) + 
    rep(seq(from = 0, by = 3, length = prod(ngrps, ningrps)/2), 
     each = ningrps) 
ord[want] <- seq_len(prod(ngrps, ningrps)) 
## ii) 
want <- ngrps * seq_len(ngrps) 
ord[want] <- seq(to = sum(ncol(df3), ncol(df4)) - 4, by = 1, length = ngrps) 
res3 <- res2[, c(1:2, ord+2)] 

這給:

> head(res3) 
    lat lon df3Var1 df3Var2 df4Var1 df3Var3 df3Var4 df4Var2 df3Var5 
1 1 1 0.2655087 0.2059746 0.9128759 0.9347052 0.4820801 0.3390729 0.8209463 
2 2 2 0.3721239 0.1765568 0.2936034 0.2121425 0.5995658 0.8394404 0.6470602 
3 3 3 0.5728534 0.6870228 0.4590657 0.6516738 0.4935413 0.3466835 0.7829328 
4 4 4 0.9082078 0.3841037 0.3323947 0.1255551 0.1862176 0.3337749 0.5530363 
5 5 5 0.2016819 0.7698414 0.6508705 0.2672207 0.8273733 0.4763512 0.5297196 
6 6 6 0.8983897 0.4976992 0.2580168 0.3861141 0.6684667 0.8921983 0.7893562 
    df3Var6 df4Var3 
1 0.47761962 0.4346595 
2 0.86120948 0.7125147 
3 0.43809711 0.3999944 
4 0.24479728 0.3253522 
5 0.07067905 0.7570871 
6 0.09946616 0.2026923 

這是你想要的順序。現在,我們可以煮到這一點功能:

myMerge <- function(x, y, ngrps, ningrps, ...) { 
    out <- merge(x, y, ...) 
    ncols <- ncol(out) - 2 
    ord <- numeric(length = ncols) 
    want <- rep(seq_len(ningrps), ngrps) + 
     rep(seq(from = 0, by = ngrps, length = prod(ngrps, ningrps)/2), 
      each = ningrps) 
    ord[want] <- seq_len(prod(ngrps, ningrps)) 
    want <- ngrps * seq_len(ngrps) 
    ord[want] <- seq(to = ncols, by = 1, length = ngrps) 
    out <- out[, c(1:2, ord+2)] 
    out 
} 

其中關於df3df4使用時上面給出:

> myMerge(df3, df4, ngrps = 3, ningrps = 2, sort = FALSE) 
    lat lon df3Var1 df3Var2 df4Var1 df3Var3 df3Var4 df4Var2 
1 1 1 0.26550866 0.2059746 0.91287592 0.93470523 0.4820801 0.3390729 
2 2 2 0.37212390 0.1765568 0.29360337 0.21214252 0.5995658 0.8394404 
3 3 3 0.57285336 0.6870228 0.45906573 0.65167377 0.4935413 0.3466835 
4 4 4 0.90820779 0.3841037 0.33239467 0.12555510 0.1862176 0.3337749 
5 5 5 0.20168193 0.7698414 0.65087047 0.26722067 0.8273733 0.4763512 
6 6 6 0.89838968 0.4976992 0.25801678 0.38611409 0.6684667 0.8921983 
7 7 7 0.94467527 0.7176185 0.47854525 0.01339033 0.7942399 0.8643395 
8 8 8 0.66079779 0.9919061 0.76631067 0.38238796 0.1079436 0.3899895 
9 9 9 0.62911404 0.3800352 0.08424691 0.86969085 0.7237109 0.7773207 
10 10 10 0.06178627 0.7774452 0.87532133 0.34034900 0.4112744 0.9606180 
    df3Var5 df3Var6 df4Var3 
1 0.8209463 0.47761962 0.4346595 
2 0.6470602 0.86120948 0.7125147 
3 0.7829328 0.43809711 0.3999944 
4 0.5530363 0.24479728 0.3253522 
5 0.5297196 0.07067905 0.7570871 
6 0.7893562 0.09946616 0.2026923 
7 0.0233312 0.31627171 0.7111212 
8 0.4772301 0.51863426 0.1216919 
9 0.7323137 0.66200508 0.2454885 
10 0.6927316 0.40683019 0.1433044 

這是你想要的東西再次。你可以調整函數的定義,所以你不需要同時指定ngrpsningrps,因爲你可以從另一個加上df3-2的列數。但是我會把它作爲練習給讀者。

+0

+1同意合併完成。 – Andrie 2012-03-01 11:15:56

+0

@skd我不太瞭解你的觀點。默認情況下,「合併」將列名作爲公共列。當然,你可以指定其他的東西。 – Andrie 2012-03-01 11:26:31

+0

我用一個例子來編輯主要問題,以澄清我的意思 – skd 2012-03-01 11:29:47

1

建議的另一個功能是cbind()。您可以指定多少個列以及哪個列與另一個數據框結合。退房的幫助部分有很好的例子: cbind help page

+0

您還需要確保兩個數據框的行的順序相同。 merge()更安全,因爲它全部爲你做。 – 2012-03-01 14:16:32

0

您可以修改你的最後一行:

res <- res[, c(1:2, order(sub("[[:alpha:]]+"", colnames(res[, -(1:2)]))) + 2)] 

那(現在的)處理多個字母字符主導模式。如果你的模式更復雜,那麼你需要提供一個例子來說明這種複雜程度。正則表達式解決方案可以輕鬆修剪所有主要的alpha或所有的alpha字符,但我們確實需要知道真正的問題有多複雜。

+0

這些列沒有任何名稱,您只需從一個數據框中取4,而從另一箇中取1。 – skd 2012-03-01 15:21:23

+0

當然,這些列有名稱。所有的數據框都有列名。 – 2012-03-01 15:25:04

+0

我的意思是沒有任何特定的名稱,只是默認的 – skd 2012-03-02 16:00:36