2014-01-30 74 views
1

我有一個有兩列的數據框:一個是字符串,另一個是整數。R:使用c聚合字符串

> rnames = sapply(1:20, FUN=function(x) paste("item", x, sep=".")) 
> x <- sample(c(1:5), 20, replace = TRUE) 
> df <- data.frame(x, rnames) 
> df 
    x rnames 
1 5 item.1 
2 3 item.2 
3 5 item.3 
4 3 item.4 
5 1 item.5 
6 3 item.6 
7 4 item.7 
8 5 item.8 
9 4 item.9 
10 5 item.10 
11 5 item.11 
12 2 item.12 
13 2 item.13 
14 1 item.14 
15 3 item.15 
16 4 item.16 
17 5 item.17 
18 4 item.18 
19 1 item.19 
20 1 item.20 

我想用「C」或「列表」功能聚集的字符串(字符)的字符串到列表或載體,而且越來越怪異的結果:

> aggregate(rnames ~ x, df, c) 
    x    rnames 
1 1  16, 6, 11, 13 
2 2    4, 5 
3 3  12, 15, 17, 7 
4 4  18, 20, 8, 10 
5 5 1, 14, 19, 2, 3, 9 

當我使用'粘貼'而不是'c',我可以看到聚合工作正常 - 但結果不是我要找的。

> aggregate(rnames ~ x, df, paste) 
    x           rnames 
1 1     item.5, item.14, item.19, item.20 
2 2         item.12, item.13 
3 3     item.2, item.4, item.6, item.15 
4 4     item.7, item.9, item.16, item.18 
5 5 item.1, item.3, item.8, item.10, item.11, item.17 

什麼我要找的是每一個聚集羣會被顯示爲矢量或點燃(因此使用c),而不是單一的字符串我與「粘貼」獲得。一些沿着以下線路(這實際上是行不通的):

> aggregate(rnames ~ x, df, c) 
    x           rnames 
1 1     item.5, item.14, item.19, item.20 
2 2         item.12, item.13 
3 3     item.2, item.4, item.6, item.15 
4 4     item.7, item.9, item.16, item.18 
5 5 item.1, item.3, item.8, item.10, item.11, item.17 

任何幫助,將不勝感激。

回答

5

你倒在data.frame通常陷阱:你的性格列是不是一個字符列,這是一個因素列!因此,數,而不是在結果中的字符:

> rnames = sapply(1:20, FUN=function(x) paste("item", x, sep=".")) 
> x <- sample(c(1:5), 20, replace = TRUE) 
> df <- data.frame(x, rnames) 
> str(df) 
'data.frame': 20 obs. of 2 variables: 
$ x  : int 2 5 5 5 5 4 3 3 2 4 ... 
$ rnames: Factor w/ 20 levels "item.1","item.10",..: 1 12 14 15 16 17 18 19 20 2 ... 

爲了防止轉換的因素,使用參數stringAsFactors=FALSE在調用data.frame

> df <- data.frame(x, rnames,stringsAsFactors=FALSE) 
> str(df) 
'data.frame': 20 obs. of 2 variables: 
$ x  : int 5 5 3 5 5 3 2 5 1 5 ... 
$ rnames: chr "item.1" "item.2" "item.3" "item.4" ... 
> aggregate(rnames ~ x, df, c) 
    x                    rnames 
1 1               item.9, item.13, item.17 
2 2                    item.7 
3 3                item.3, item.6, item.19 
4 4               item.12, item.15, item.16 
5 5 item.1, item.2, item.4, item.5, item.8, item.10, item.11, item.14, item.18, item.20 

另一種解決方案,以避免轉換系數功能I

> df <- data.frame(x, I(rnames)) 
> str(df) 
'data.frame': 20 obs. of 2 variables: 
$ x  : int 3 5 4 5 4 5 3 3 1 1 ... 
$ rnames:Class 'AsIs' chr [1:20] "item.1" "item.2" "item.3" "item.4" ... 

摘自?I

函數data.frame。通過將對象封裝在 中的I()中來保護對象,調用data.frame將禁止將字符向量轉換爲 因子並刪除名稱,並確保將矩陣插入爲單列的 。我也可以用來保護要添加到數據幀的對象 ,或者通過as.data.frame將其轉換爲數據幀 。

它通過在對象的 類中預先添加類「AsIs」來實現此目的。類「AsIs」有其自己的一些方法,包括[, as.data.frame,打印和格式。

+0

很酷。我學到了一些東西! :-) – DataWookie

2

我不確定你正在尋找什麼......所以也許有些參考輸出可以給我們一個我們正在瞄準的東西的想法嗎?

但是,由於代碼的最後一點似乎是接近你所追求的,也許像下面這樣的解決方案將工作:

> library(plyr) 
> ddply(df, .(x), summarize, rnames = paste(rnames, collapse = "|")) 
    x           rnames 
1 1       item.9|item.11|item.20 
2 2     item.1|item.2|item.15|item.16 
3 3         item.7|item.8 
4 4   item.4|item.5|item.6|item.12|item.13 
5 5 item.3|item.10|item.14|item.17|item.18|item.19 

可以改變各個元素是如何通過改變粘在一起paste()的collapse參數。

另外,如果你只想有每個組的縮放的矢量,那麼你可以使用這個:

> df$rnames = as.character(df$rnames) 
> L = dlply(df, .(x), function(df) {df$rnames}) 
> L 
$`1` 
[1] "item.9" "item.11" "item.20" 

$`2` 
[1] "item.1" "item.2" "item.15" "item.16" 

$`3` 
[1] "item.7" "item.8" 

$`4` 
[1] "item.4" "item.5" "item.6" "item.12" "item.13" 

$`5` 
[1] "item.3" "item.10" "item.14" "item.17" "item.18" "item.19" 

attr(,"split_type") 
[1] "data.frame" 
attr(,"split_labels") 
    x 
1 1 
2 2 
3 3 
4 4 
5 5 

這給你載體列表,這是你所追求的。每個組可以被索引出結果列表中的:

> L[[1]] 
[1] "item.9" "item.11" "item.20" 
+0

我編輯了這個問題。我試圖得到的是,每個聚合組將被作爲一個向量/列表返回,而不是一個單一的字符串,這是我'粘貼'。 – Roy2012