2015-10-06 37 views
3

我想重新組織我的數據,基本上是一個data.frames列表。 其元素代表感興趣的主題(A和B),在兩次(1和2)中收集對x和y的觀察。 我想使這個列表包含涉及主題的data.frames,其中收集x和y的信息將作爲新變量存儲在相應的data.frames中,而不是元素名稱:在R中,根據元素名稱(rbind和指示符變量)重組列表

library('rlist') 

A1 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 
A2 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 
B1 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 
B2 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 

list <- list(A1=A1,A2=A2,B1=B1,B2=B2) 

A <- do.call(rbind,list.match(list,"A")) 
B <- do.call(rbind,list.match(list,"B")) 

list <- list(A=A,B=B) 
list <- lapply(list,function(x) { 
     y <- data.frame(x) 
     y$class <- c(rep.int(1,2),rep.int(2,2)) 
     return(y) 
}) 

> list 
$A 
     x y class 
A1.1 66 96  1 
A1.2 76 58  1 
A2.1 50 93  2 
A2.2 57 12  2 

$B 
     x y class 
B1.1 58 56  1 
B1.2 69 15  1 
B2.1 77 77  2 
B2.2 9 9  2 

在我的現實世界的問題中,有大約500個科目,並不總是兩次,不同數量的觀察。

所以我上面的示例只是爲了說明我想要獲取的位置,並且我堅持如何傳遞給do.call-rbind,它應該基於元素名稱將特定於主體的元素綁定爲新列表元素放在一起,同時分配一個新的變量。

對我來說,這是一個有點模糊的任務,最接近我得到的是rlist包。 This問題是相關的,但使用unique來識別元素,而在我的情況下,它似乎更多的正則表達式問題。

我很樂意甚至如何使用谷歌,任何關鍵字進行進一步的研究等

+1

如果您提供了一些真實的數據框名稱,有人試圖幫助您可以爲您編寫更準確的正則表達式。 –

+0

我認爲在更抽象的層面上留下正則表達式問題會讓我的問題變得混亂。當然,stackoverflow再次證明對周圍的人有幫助。我會在下面處理你的答案,並回來:) – leokrkr

回答

0

聽起來好像你做了很多體操的,因爲你心裏有一個具體形式。我想建議的是首先嚐試使數據tidy。在沒有閱讀鏈接的情況下,快速總結就是將您的數據放入一個數據框中,並且可以輕鬆處理。

快速版本的答案(這裏我用lst代替list的名稱,以避免混淆內置list)的是要做到這一點:

do.call(rbind, 
    lapply(seq(lst), function(i) { 
    lst[[i]]$type <- names(lst)[i]; lst[[i]] 
    }) 
) 

這將完成是創建一個單一的數據框,其中包含「type」列,其中包含該行出現的列表項的名稱。

使用您的初始數據的略微簡化的版本:

lst <- list(A1=data.frame(x=rnorm(5)), A2=data.frame(x=rnorm(3)), B=data.frame(x=rnorm(5))) 
lst 
$A1 
      x 
1 1.3386071 
2 1.9875317 
3 0.4942179 
4 -0.1803087 
5 0.3094100 

$A2 
      x 
1 -0.3388195 
2 1.1993115 
3 1.9524970 

$B 
      x 
1 -0.1317882 
2 -0.3383545 
3 0.8864144 
4 0.9241305 
5 -0.8481927 

,然後應用的神奇功能

df <- do.call(rbind, 
    lapply(seq(lst), function(i) { 
    lst[[i]]$type <- names(lst)[i]; lst[[i]] 
    }) 
) 
df 
      x type 
1 1.3386071 A1 
2 1.9875317 A1 
3 0.4942179 A1 
4 -0.1803087 A1 
5 0.3094100 A1 
6 -0.3388195 A2 
7 1.1993115 A2 
8 1.9524970 A2 
9 -0.1317882 B 
10 -0.3383545 B 
11 0.8864144 B 
12 0.9241305 B 
13 -0.8481927 B 

從這裏我們可以處理我們的心靈內容;通過像df$subject <- gsub("[0-9]*", "", df$type)這樣的操作來提取type的非數字部分,而像split這樣的工具可用於生成您在問題中提到的子列表。

此外,一旦它在這種形式下,你可以使用功能,如byaggregate或庫,例如dplyrdata.table來進行數據分析做更先進的拆分申請,結合操作。

+0

只要我的名聲不允許upvotes,我會在這裏留下我的感謝。我需要更多的時間來處理你的答案,而不是你們寫的! – leokrkr

2

從您提供的數據說明:我們做的正則表達式調用

subj <- sub("[A-Z]*", "", names(lst)) 
newlst <- Map(function(x, y) {x[,"class"] <- y;x}, lst, subj) 

第一隔離將在class列中的數字。在這種情況下,我匹配大寫字母並刪除它們,留下數字。因此,"A1"變成"1"。請注意,真實姓名將表示不同的正則表達式模式。

然後我們使用Map爲每個數據幀創建一個新列並保存到名爲newlst的新列表中。 Map接受每個參數的第一個元素並執行該函數,然後繼續處理每個對象元素。因此,首先使用lst中的第一個數據幀和subj中的第一個數據幀。我使用的匿名函數是function(x,y) {x[, "class"] <- y; x}。它有兩個參數。第一個是數據框,第二個是列值。

現在往前走容易得多。我們可以創建一個名爲uniq.nmes的向量來獲取我們將要組合的數據幀的名稱。其中"A1"將變爲"A"。然後我們就可以rbind在那場比賽:

uniq.nmes <- unique(sub("\\d", "", names(lst))) 
lapply(uniq.nmes, function(x) { 
    do.call(rbind, newlst[grep(x, names(newlst))]) 
}) 
# [[1]] 
#  x y class 
# A1.1 1 79  1 
# A1.2 30 13  1 
# A2.1 90 39  2 
# A2.2 43 22  2 
# 
# [[2]] 
#  x y class 
# B1.1 54 59  1 
# B1.2 83 90  1 
# B2.1 85 36  2 
# B2.2 91 28  2 

數據

A1 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 
A2 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 
B1 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 
B2 <- data.frame(x=sample(1:100,2),y=sample(1:100,2)) 

lst <- list(A1=A1,A2=A2,B1=B1,B2=B2) 
相關問題