【发布时间】:2015-05-12 09:39:36
【问题描述】:
我有一个需要拆分为两个表以满足 Codd 的第三范式的数据框。在一个简单的情况下,原始数据框看起来像这样:
library(lubridate)
> (df <- data.frame(hh_id = 1:2,
income = c(55000, 94000),
bday_01 = ymd(c(20150309, 19890211)),
bday_02 = ymd(c(19850911, 20000815)),
gender_01 = factor(c("M", "F")),
gender_02 = factor(c("F", "F"))))
hh_id income bday_01 bday_02 gender_01 gender_02
1 1 55000 2015-03-09 1985-09-11 M F
2 2 94000 1989-02-11 2000-08-15 F F
当我使用收集功能时,它会警告属性不相同,并且会丢失性别因素和 bday 的 lubridate(或真实示例中的其他属性)。是否有一个很好的 tidyr 解决方案来避免丢失每列的数据类型?
library(tidyr)
> (person <- df %>%
select(hh_id, bday_01:gender_02) %>%
gather(key, value, -hh_id) %>%
separate(key, c("key", "per_num"), sep = "_") %>%
spread(key, value))
hh_id per_num bday gender
1 1 01 1425859200 M
2 1 02 495244800 F
3 2 01 603158400 F
4 2 02 966297600 F
Warning message:
attributes are not identical across measure variables; they will be dropped
> lapply(person, class)
$hh_id
[1] "integer"
$per_num
[1] "character"
$bday
[1] "character"
$gender
[1] "character"
我可以想出一种方法,即分别收集具有相同数据类型的每组变量,然后连接所有表,但必须有一个更优雅的解决方案,但我错过了。
【问题讨论】:
-
我认为目前没有一个优雅的解决方案 :( 对于这种情况,我 认为 收集可能需要创建一个列表列,以便属性不会会迷路。但我认为这会很慢,并且可能会让人们感到困惑。
-
@hadley 啊,我明白了。是的,我正在编写一个返回列表结果的函数,而且速度非常慢。我现在正在为此寻找更好的解决方案。