我想了解"融化"适用于复杂情况。我在很简单的情况下看过很多关于使用这些软件包的帖子和博客 - 但不是更困难的。例如:
假设我在数据框中有以下数据:
CA UNIT SCP DATE1 TIME1 DESC1 ENTRIES1 EXITS1
1 A002 R051 02-00-00 07-27-13 00:00:00 REGULAR 4209603 1443585
2 A002 R051 02-00-00 07-28-13 08:00:00 REGULAR 4210490 1443821
3 A002 R051 02-00-00 07-29-13 16:00:00 REGULAR 4211586 1444302
4 A002 R051 02-00-00 07-30-13 14:01:46 LOGON 4213192 1444700
5 A002 R051 02-00-00 07-30-13 16:00:00 REGULAR 4213333 1444737
6 A002 R051 02-00-00 08-01-13 00:00:00 REGULAR 4215894 1445274`
并继续向右列(抱歉,我无法在代码块中正确格式化):
`DATE2 TIME2 DESC2 ENTRIES2 EXITS2
1 07-27-13 08:00:00 REGULAR 4209663 1443616
2 07-28-13 16:00:00 REGULAR 4210775 1443921
3 07-30-13 00:00:00 REGULAR 4212845 1444369
4 07-30-13 14:02:18 DOOR OPEN 4213192 1444700
5 07-31-13 00:00:00 REGULAR 4214345 1444823
6 08-01-13 08:00:00 REGULAR 4215977 1445362`
我希望将其融入具有以下格式的数据框中:
CA UNIT SCP DATE TIME DESC ENTRIES EXITS
1 A002 R051 02-00-00 07-27-13 00:00:00 REGULAR 4209603 1443585
2 A002 R051 02-00-00 07-28-13 08:00:00 REGULAR 4210490 1443821
3 A002 R051 02-00-00 07-29-13 16:00:00 REGULAR 4211586 1444302
4 A002 R051 02-00-00 07-30-13 14:01:46 LOGON 4213192 1444700
5 A002 R051 02-00-00 07-30-13 16:00:00 REGULAR 4213333 1444737
6 A002 R051 02-00-00 08-01-13 00:00:00 REGULAR 4215894 1445274
7 A002 R051 02-00-00 07-27-13 08:00:00 REGULAR 4209663 1443616
8 A002 R051 02-00-00 07-28-13 16:00:00 REGULAR 4210775 1443921
9 A002 R051 02-00-00 07-30-13 00:00:00 REGULAR 4212845 1444369
10A002 R051 02-00-00 07-30-13 14:02:18 DOOR OPEN 4213192 1444700
11A002 R051 02-00-00 07-31-13 00:00:00 REGULAR 4214345 1444823
12A002 R051 02-00-00 08-01-13 08:00:00 REGULAR 4215977 1445362
这里面临的挑战是我想要的专栏"融化"有不同的数据类型。我读到的所有帖子都非常简单,并且假设所有熔化的列都具有相同的数据类型,并且将属于漂亮的键/值对。这显然不是这种情况。
我找到了另一篇帖子,表明可以使用'替换'来完成重组。来自统计数据。我明白了。但是如果dplyr,reshape2和tidyr无法用于更复杂的真实场景,那么它的实际用途是什么?
请说明如何使用tidyr,dplyr或reshape2执行此操作。
提前谢谢!
答案 0 :(得分:6)
如果您查看reshape
默认分隔符为?reshape
,并且.
指定为{{1>,则来自R的sep
选项然后它将使用正则表达式来分割适合您的情况的""
列名称。如果您不需要,可以删除[A-Za-z][0-9]
和time
变量:
id
reshape(df, varying = 4:13, dir = "long", sep = "")
答案 1 :(得分:3)
可能有一个很好的tidyr
和/或data.table
解决方案,但你也可以在基数R中执行以下操作来堆叠两个五列组:
names(dat) = gsub("1|2", "", names(dat))
rbind(dat[,1:8], dat[,c(1:3,9:13)])
CA UNIT SCP DATE TIME DESC ENTRIES EXITS 1 A002 R051 02-00-00 07-27-13 00:00:00 REGULAR 4209603 1443585 2 A002 R051 02-00-00 07-28-13 08:00:00 REGULAR 4210490 1443821 3 A002 R051 02-00-00 07-29-13 16:00:00 REGULAR 4211586 1444302 4 A002 R051 02-00-00 07-30-13 14:01:46 LOGON 4213192 1444700 5 A002 R051 02-00-00 07-30-13 16:00:00 REGULAR 4213333 1444737 6 A002 R051 02-00-00 08-01-13 00:00:00 REGULAR 4215894 1445274 7 A002 R051 02-00-00 07-27-13 08:00:00 REGULAR 4209663 1443616 8 A002 R051 02-00-00 07-28-13 16:00:00 REGULAR 4210775 1443921 9 A002 R051 02-00-00 07-30-13 00:00:00 REGULAR 4212845 1444369 10 A002 R051 02-00-00 07-30-13 14:02:18 DOOR_OPEN 4213192 1444700 11 A002 R051 02-00-00 07-31-13 00:00:00 REGULAR 4214345 1444823 12 A002 R051 02-00-00 08-01-13 08:00:00 REGULAR 4215977 1445362
在您的示例中,您只有两个需要堆叠的五列集。如果你有更多这样的群体,你可以做这样的事情,以避免大量的硬编码:
dat = lapply(seq(4,ncol(dat),5), function(i) {
tmp = dat[, c(1:3, i:(i+4))]
names(tmp) = gsub("[0-9]", "", names(tmp))
tmp
})
dat = do.call(rbind, dat)
答案 2 :(得分:2)
我们可以使用melt
中的data.table
轻松完成此操作,因为它可能需要多个measure
patterns
。
library(data.table)
melt(setDT(df), measure = patterns(c("DATE", "TIME", "DESC", "ENTRIES",
"EXITS")), value.name = c('DATE', 'TIME', 'DESC', 'ENTRIES',
'EXITS'))[, variable := NULL][]
# CA UNIT SCP DATE TIME DESC ENTRIES EXITS
#1: A002 R051 02-00-00 07-27-13 00:00:00 REGULAR 4209603 1443585
#2: A002 R051 02-00-00 07-28-13 08:00:00 REGULAR 4210490 1443821
#3: A002 R051 02-00-00 07-29-13 16:00:00 REGULAR 4211586 1444302
#4: A002 R051 02-00-00 07-30-13 14:01:46 LOGON 4213192 1444700
#5: A002 R051 02-00-00 07-30-13 16:00:00 REGULAR 4213333 1444737
#6: A002 R051 02-00-00 08-01-13 00:00:00 REGULAR 4215894 1445274
#7: A002 R051 02-00-00 07-27-13 08:00:00 REGULAR 4209663 1443616
#8: A002 R051 02-00-00 07-28-13 16:00:00 REGULAR 4210775 1443921
#9: A002 R051 02-00-00 07-30-13 00:00:00 REGULAR 4212845 1444369
#10:A002 R051 02-00-00 07-30-13 14:02:18 DOOR OPEN 4213192 1444700
#11:A002 R051 02-00-00 07-31-13 00:00:00 REGULAR 4214345 1444823
#12:A002 R051 02-00-00 08-01-13 08:00:00 REGULAR 4215977 1445362
答案 3 :(得分:1)
在tidyr
中,您需要gather
加长,修改列名称,然后spread
返回广泛。由于spread
对索引非常挑剔,因此您需要添加一个唯一的ID列,dplyr::add_rownames
可以很好地执行此操作:
library(tidyr)
library(dplyr)
df %>% add_rownames() %>%
# gather to long form
gather(var, val, DATE1:EXITS2) %>%
# separate ID suffix from variable name by position
separate(var, c('var', 'id'), sep = -2) %>%
# spread back to wide form
spread(var, val, convert = TRUE) %>%
# clean up extra columns
select(-rowname, -id)
## # A tibble: 12 x 8
## CA UNIT SCP DATE DESC ENTRIES EXITS TIME
## * <fctr> <fctr> <fctr> <chr> <chr> <int> <int> <chr>
## 1 A002 R051 02-00-00 07-27-13 REGULAR 4209603 1443585 00:00:00
## 2 A002 R051 02-00-00 07-27-13 REGULAR 4209663 1443616 08:00:00
## 3 A002 R051 02-00-00 07-28-13 REGULAR 4210490 1443821 08:00:00
## 4 A002 R051 02-00-00 07-28-13 REGULAR 4210775 1443921 16:00:00
## 5 A002 R051 02-00-00 07-29-13 REGULAR 4211586 1444302 16:00:00
## 6 A002 R051 02-00-00 07-30-13 REGULAR 4212845 1444369 00:00:00
## 7 A002 R051 02-00-00 07-30-13 LOGON 4213192 1444700 14:01:46
## 8 A002 R051 02-00-00 07-30-13 DOOR OPEN 4213192 1444700 14:02:18
## 9 A002 R051 02-00-00 07-30-13 REGULAR 4213333 1444737 16:00:00
## 10 A002 R051 02-00-00 07-31-13 REGULAR 4214345 1444823 00:00:00
## 11 A002 R051 02-00-00 08-01-13 REGULAR 4215894 1445274 00:00:00
## 12 A002 R051 02-00-00 08-01-13 REGULAR 4215977 1445362 08:00:00