2016-08-18 18 views
0

我有一個寬格式的數據框的列表,第1列有一個因子變量,第2列又有一個年度化數據。我想要繪製這些數據。這樣做需要將它們重新塑造成長格式。這裏是一個數據幀的例子:我平時此使用reshape()R整形變得很長,使用對象作爲輸入

# SAMPLE DATA 
x <- structure(list(State = structure(1:3, .Label = c("Alabama", "Alaska", "Arizona", "Arkansas"), class = "factor"), Green.And.Blue.Score.2001 = c(0L, 40L, 65L), Green.And.Blue.Score.2002 = c(20L, 5L, 60L), Green.And.Blue.Score.2003 = c(35L, 15L, 30L)), .Names = c("State", "Green.And.Blue.Score.2001", "Green.And.Blue.Score.2002", "Green.And.Blue.Score.2003"), row.names = c(NA, 3L), class = "data.frame") 

x 
# State Green.And.Blue.Score.2001 Green.And.Blue.Score.2002 Green.And.Blue.Score.2003 
#1 Alabama   0       20       35 
#2 Alaska   40       5       15 
#3 Arizona   65       60       30 

。例如,這工作得很好:

# RESHAPE WIDE TO LONG (MANUALLY) 
y <- reshape(x, 
    idvar = 'State', 
    varying = c('Green.And.Blue.Score.2001', 'Green.And.Blue.Score.2002', 'Green.And.Blue.Score.2003'), 
    v.names = 'Green.And.Blue.Score.', 
    times = c('2001', '2002', '2003'), 
direction = 'long') 

y 
# State time Green.And.Blue.Score. 
# Alabama 2001  0 
# Alaska 2001  40 
# Arizona 2001  65 
# Alabama 2002  20 
# Alaska 2002  5 
# Arizona 2002  60 
# Alabama 2003  35 
# Alaska 2003  15 
# Arizona 2003  30 

但是,我不想必須手動輸入idvarvaryingv.nametimes變量數十我有數據幀,並且因爲一些列名相當長且複雜,並且從數據幀到數據幀有很大差異,簡單的reshape()命令不能自動將它們解壓縮。我的想法是創建一個函數,以獲得從所述數據幀的那些輸入,該前體其如下:

# RESHAPE WIDE TO LONG (FUNCTIONALIZED) 
id <- noquote(paste("'", names(x[1]), "'", sep = "")) 
va <- noquote(paste("c('", paste(names(x)[2:length(x)], collapse = "', '"), "')", sep = "")) 
vn <- noquote(paste("'", sub("(\\..*)$", ".", names(x)[2]) , "'", sep = "")) 
ti <- noquote(paste("c('", paste(sub(".*(\\d{4})$", "\\1", names(x[2:length(x)])), collapse = "', '"), "')", sep = "")) 

每個這些匹配的從#RESHAPE WIDE TO LONG (MANUALLY)idvarvaryingv.name,和times輸入端的輸出以上:

id 
# 'State' 
va 
# c(''Green.And.Blue.Score.2001', ''Green.And.Blue.Score.2002', ''Green.And.Blue.Score.2003') 
vn 
# ''Green.And.Blue.Score.' 
ti 
# c('2001', '2002', '2003') 

但是,當我嘗試在reshape()函數中使用這些對象,我得到一個錯誤信息:

y <- reshape(x, 
    idvar = id, 
    varying = va, 
    v.names = vn, 
    times = ti, 
direction = 'long') 

Error in [.data.frame(data, , varying[[i]][1L]) : undefined columns selected

我敢肯定我的'functionalize'reshape()的解決方案並不理想。我應該做些什麼呢?

+0

的'noquote'功能不會產生的R表達似乎是你所期望的。它返回一個仍然是字符值的noquote類的項目,但它具有不同的print-to-console方法。 '粘貼'ng引號會引起進一步的混淆。 –

回答

2

爲從名稱中提取的材料加上引號會導致錯誤。這是該代碼的簡化。請注意,我刪除了v.names和次數,因爲當列名由「。」正確分隔時,它們是自動計算的。

y <- reshape(x, 
    idvar = names(x)[1], 
    varying = names(x)[-1], 

direction = 'long') 
y 
#-----  
      State time Score 
Alabama.2001 Alabama 2001  0 
Alaska.2001 Alaska 2001 40 
Arizona.2001 Arizona 2001 65 
Alabama.2002 Alabama 2002 20 
Alaska.2002 Alaska 2002  5 
Arizona.2002 Arizona 2002 60 
Alabama.2003 Alabama 2003 35 
Alaska.2003 Alaska 2003 15 
Arizona.2003 Arizona 2003 30 

如果我們用這條新的例子中,我們可以在該給出一個合理的結果,「.S」獲得了「分裂」。第一階段和「拆分」模式之間的塔名的文本被移動到列名,而導致狀態名稱和年獲得appeanded一起作爲一個rowname:

y <- reshape(x, 
     idvar = names(x)[1], 
    varying = names(x)[-1], 
    split = list(regexp = "\\.S", include = TRUE), 
    direction = 'long') 
    y 

        State  time Green.And.Blue. 
Alabama.Score.2001 Alabama Score.2001    0 
Alaska.Score.2001 Alaska Score.2001    40 
Arizona.Score.2001 Arizona Score.2001    65 
Alabama.Score.2002 Alabama Score.2002    20 
Alaska.Score.2002 Alaska Score.2002    5 
Arizona.Score.2002 Arizona Score.2002    60 
Alabama.Score.2003 Alabama Score.2003    35 
Alaska.Score.2003 Alaska Score.2003    15 
Arizona.Score.2003 Arizona Score.2003    30 
+0

謝謝@ 42-,但我想我的示例數據太簡化了。我的實際數據中的變量名稱比較複雜一點,比如'Score.2001',它們就像'Green.And.Blue.Score.2001',它們的長度在每個數據幀列表(儘管它們總是以四位數結尾)。所以當我在上面運行你的簡化代碼時,我得到這個錯誤:'猜測錯誤(變化):未能從他們的名字中猜出時變變量,這就是讓我陷入瘋狂的'paste()'路徑和'noquote()'。我應該用更長的變量名更新OP嗎? – coip

+1

總而言之,是的。你會注意到,如果你看''reshape',它允許你構造一個正則表達式來處理更復雜的情況。在另一種情況下,應該可以構建一個正則表達式,它將在最後一個「」。「」處分割 –