整理数据并将键值重塑为宽格式

tidying data and reshaping key-value to wide format

老实说,这对我来说不是一个简单的问题。找了好久好像没有类似的问题

下面是我的数据的一些行和列:

                                V1        V2       V3
1 74c1c25f4b283fa74a5514307b0d0278 1#11:2241 1#10:249
2 08f5b445ec6b29deba62e6fd8b0325a6  20#7:249  20#5:83
3 4b7f6f4e2bf237b6cc58f57142bea5c0  4#16:249   24:913

因此,单元格的格式类似于 "class(#subclass):value"。我想做一个 table 这样的:

                                V1      1#10     1#11    4#16    20#5    20#7    24
1 74c1c25f4b283fa74a5514307b0d0278       249     2241       0       0       0     0      
2 08f5b445ec6b29deba62e6fd8b0325a6         0        0       0      83     249     0
3 4b7f6f4e2bf237b6cc58f57142bea5c0         0        0     249       0       0   913

因为之前没有接触过这种数据结构,所以不确定这样是不是最好的存储方式。但到目前为止,这是我唯一能想到的 table 格式。如果您对此有什么建议,欢迎留言。

然后,我首先解析如下:

                            V1     V2_1_1 V2_1_2 V2_2_1 V3_1_1 V3_1_2 V3_2_1
1 74c1c25f4b283fa74a5514307b0d0278      1     11   2241      1     10    249
2 08f5b445ec6b29deba62e6fd8b0325a6     20      7    249     20      5     83
3 4b7f6f4e2bf237b6cc58f57142bea5c0      4     16    249     24     NA    913

现在,我不知道如何将它转换成我想要的 table 格式。我可以使用 R 中的任何包吗?

下面附上两个链接

原始数据:https://www.dropbox.com/s/aqay5dn4r3m3kdp/temp1TrainPoiFile.R?dl=0

解析数据: https://www.dropbox.com/s/0oj8ic1pd2rew0h/temp3TrainPoiFile.R?dl=0

非常感谢您的帮助。如果有任何问题,请发表评论。

感谢沃尔特和杰克的回答。我用 tidyr 来解决这个问题。以下是我的做法。

读取文件

source("temp1TrainPoiFile.R")

将列收集到键值对

temp2TrainPoiFile <-  temp1TrainPoiFile %>% gather( key=V1, value=data, -V1)

提取到两列

temp3TrainPoiFile <- temp2TrainPoiFile %>% extract(col=data, into=c("class","value"), regex="(.*):(.*)")

添加行号

row <- 1:nrow(temp3TrainPoiFile)
temp3TrainPoiFile <- cbind(row, temp3TrainPoiFile)

将键值分布到两列

TrainPoiFile <- temp3TrainPoiFile %>% spread(key=class, value=value, fill=0)

读入数据

data <- source("temp1TrainPoiFile.R")[[1]]

适当的 NA

data[data == ""] <- NA

将其重塑为长格式

data <- do.call(rbind, lapply(split(data, data[,"V1"]), function(n) {
                                  id <- n[,1]
                                  n <- na.omit(unlist(n[,-1]))
                                  n <- strsplit(n, ":")
                                  n <- do.call(rbind, lapply(n, function(m) data.frame(column = m[1], value = m[2])))
                                  n <- data.frame(id = id, n)
                                  n}))

准备 for 循环以将值插入到新创建的矩阵中

id <- unique(data[,"id"])
column <- unique(data[,"column"])
mat <- matrix(data = NA, nrow = length(id), ncol = length(column))
rownames(mat) <- id
colnames(mat) <- column

插入值

for(i in 1:nrow(data)) {
    mat[data[i, "id"], data[i, "column"]] <- data[i,"value"]}

这看起来是使用 tidyr 包的一个很好的例子。使用gather转换成两列数据框,以V1列为键,其他列为值列命名为dataextract分割[=14] =] 列转换为 classvalue 列,然后 spreadclass 列用作新列名,将 value 列用作值。代码看起来像:

library(tidyr)
library(dplyr)
class_table <- df %>% mutate(row = 1:nrow(.)) %>% 
               gather( key=V1, value=data, -c(V1,row)) %>%
               extract(col=data, into=c("class","value"), regex="(.*):(.*)") %>%
               spread(key=class, value=value, fill=0)

已编辑以确保行标识符的唯一性。 mutate 需要 dplyr 包。