将面板数据宽格式转换为长格式

5

我正在努力将一个面板数据集从宽格式转换为长格式。数据集如下:

ID | KP1_430a | KP1_430b | KP1_430c | KP2_430a | KP2_430b | KP2_430c | KP1_1500a | ...  
1     ....
2     ....

KP1; KP2 到 KP7 描述了波浪。

a,b 到 f 描述了一个特定的项目。(例如,派对 A 的从左到右的放置)

我希望将这些数据转换为长格式。就像这样:

ID | Party | Wave | 430 | 1500  
 1     1       1     ..    ..
 1     2       1     ..    ..
 .     .       .          
 1     1       2     ..    ..
 .     .       .         
 2     1       1     ..    ..  

我尝试使用reshape函数。但是我在同时重塑时间和各个方面时遇到了问题。

以下是一个小的数据框示例。

data <- data.frame(matrix(rnorm(10),2,10))  
data[,1] <- 1:2  
names(data) <- c("ID","KP1_430a" , "KP1_430b" , "KP1_430c" , "KP2_430a" , "KP2_430b ", "KP2_430c ", "KP1_1500a" ,"KP1_1500b", "KP1_1500c")

这是我到目前为止的进展。
  data_long <- reshape(data,varying=list(names(data)[2:4],names(data)[5:7], names(data[8:10]),  
                            v.names=c("KP1_430","KP2_430","KP1_1500"),  
                           direction="long", timevar="Party")

问题在于:如何以长格式获取时变变量?是否有更优雅的方法来重塑这个数据?在上面的代码中,我必须为每个波和变量输入名称(names(data)[2:4])。对于这个小数据框来说还好,但数据集要大得多。
编辑:如何手动完成此转换:实际上我已经完成了这个过程,但留下了一个长达一页的代码文件。
首先,将KP1_430a和KP1_1500a与ID、Time=1和Party=1列绑定。其次,为所有党派[b-f]创建相同的对象,分别更改党派索引,并按行附加它们。依次对剩余的波[2-7]执行步骤一和步骤二,分别更改党派和时间变量,并逐行附加它们。

如果您想在长格式中为430和1500分别设置列,则宽格式中这些条件的数据量应该相等。按照您目前的方式,1500列中会有很多NA值...或者您是希望这样吗? - John
哦,这可能有点棘手。对于这两个变量,波浪(1-7)和派对物品(a-f)的数量是相等的。因此:KP [1-7] _430 [a-f],KP [1-7] _1500 [a-f]。 - lstoetze
然而,对于数据集中的某些变量,存在以下情况:(a)仅有某些波次的数据-例如KP[146]_1640[a-f],或者(b)不属于特定方面-例如KP[1-7]_1490。 - lstoetze
2个回答

4
通常情况下,可以分两步进行操作:首先使用melt将数据变成“高”格式(除非已经是这种格式),然后再使用dcast将其转换为更宽的格式。
library(reshape2)
library(stringr)

# Tall format
d <- melt(data, id.vars="ID")

# Process the column containing wave and party
d1 <- str_match_all( 
  as.character( d$variable ), 
  "KP([0-9])_([0-9]+)([a-z])" 
)
d1 <- do.call( rbind, d1 )
d1 <- d1[,-1]
colnames(d1) <- c("wave", "number", "party")
d1 <- as.data.frame( d1)
d <- cbind( d, d1 )

# Convert to the desired format
d <- dcast( d, ID + wave + party ~ number )

0

目前你的Wave数据在变量名中,需要使用一些字符串处理来提取它。我用melt没有遇到任何问题。

mdat <- melt(data, id.vars="ID")
mdat$wave=sub("KP", "", sub("_.+$", "", mdat$variable)) # remove the other stuff
mdat

您的描述目前过于简略,我无法确定如何派生“Party”变量的规则,因此也许您可以编辑您的问题以展示人类如何完成这个步骤......然后我们可以向计算机展示如何完成它。

编辑:如果原始列名称中的最后一个小写字母是 Vincent 所想的 Party,则可以修剪这些名称中的尾随空格并提取:

mdat$var <- sub("\\s", "", (as.character(mdat$variable)))
mdat$party=substr( mdat$var, nchar(mdat$var), nchar(mdat$var))
#--------------
> mdat
   ID  variable      value wave party       var
1   1  KP1_430a  0.7220627    1     a  KP1_430a
2   2  KP1_430a  0.9585243    1     a  KP1_430a
3   1  KP1_430b -1.2954671    1     b  KP1_430b
4   2  KP1_430b  0.3393617    1     b  KP1_430b
5   1  KP1_430c -1.1477627    1     c  KP1_430c
6   2  KP1_430c -1.0909179    1     c  KP1_430c
<snipped output>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接