在大多数列具有多个值

时间:2017-02-01 14:23:06

标签: r reshape reshape2 data-management

我的数据如下:

IDnum   zipcode   City          County   State
10011   36006     Billingsley   Autauga  AL 
10011   36022     Deatsville    Autauga  AL
10011   36051     Marbury       Autauga  AL
10011   36051     Prattville    Autauga  AL
10011   36066     Prattville    Autauga  AL
10011   36067     Verbena       Autauga  AL
10011   36091     Selma         Autauga  AL
10011   36703     Jones         Autauga  AL
10011   36749     Plantersville Autauga  AL
10011   36758     Uriah         Autauga  AL
10011   36480     Atmore        Autauga  AL
10011   36502     Bon Secour    Autauga  AL

我有一个zipcodes列表,它们包含的城市以及它们所在的县/州.IDnum =县和州的数值,合并。列表是您现在看到的格式,我需要将其从长到宽/垂直到水平重新整形,其中IDnum变量成为唯一标识符,所有其他可能的值组合变为宽变量。

IDnum  zip1   city1        county1  state1  zip2   city2       county2
10011  36006  Billingsley  Autauga  AL      36022  Deatsville  Autauga

这只是数据集的示例,它包含了美国的每个zip,并包含更多变量。我已经看到了与此类似的其他问题和答案,但并不是几乎每列都有多个值的地方。

SPSS和STATA中的命令将以这种方式重塑数据,在SPSS中我可以运行Restructure / Cases to Vars命令,将我的初始数据集中的11个变量转换为大约1750,b / c一个县有超过290个拉链并且它将大多数其他变量复制290次以上。这将创建许多空白,但我需要将其重新整形为一个非常长的水平文件。

我查看了reshape和reshape2,并挂断了'default to length'错误消息。我确实得到了熔化/ dcast来进行排序工作,但这会创建一个变量,它是所有值的列表,而不是为每个值创建变量。

melted_dupes <- melt(zip_code_list_dupes, id.vars= c("IDnum"))
HRZ_dupes <- dcast(melted_dupes, IDnum ~ variable, fun.aggregate = list) 

我曾尝试过tidyr和dplyr,但在语法上迷失了方向。有点惊讶的是,没有一个命令数据类似于其他包中的内置命令,让我假设有,我只是没有想出来。

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

在按reshape添加连续计数后,您可以使用基函数IDnum执行此操作。假设您的数据存储在名为data.frame的{​​{1}}中:

df

提供名为&#34; time&#34;的连续计数的新列。现在我们可以df2 <- within(df, count <- ave(rep(1,nrow(df)),df$IDnum,FUN=cumsum)) 进行宽幅格式化

reshape
  IDnum zipcode.1      City.1 County.1 State.1 zipcode.2     City.2 County.2 State.2 zipcode.3  City.3 County.3 State.3 zipcode.4     City.4 County.4 State.4
1 10011     36006 Billingsley  Autauga      AL     36022 Deatsville  Autauga      AL     36051 Marbury  Autauga      AL     36051 Prattville  Autauga      AL

(输出截断,一直到zipcode.12等)

答案 1 :(得分:0)

可能有更有效的方法,但请尝试以下方法。 我使用了自己的(示例)数据集,与您的数据集非常相似。 逐步运行该过程以查看其工作原理,因为您必须修改代码中的某些内容。

library(dplyr)
library(tidyr)

# get example data
dt = data.frame(id = c(1,1,1,2,2),
zipcode = c(4,5,6,7,8),
city = c("A","B","C","A","C"),
county = c("A","B","C","A","C"),
state = c("A","B","C","A","C"))

dt

#   id zipcode city county state
# 1  1       4    A      A     A
# 2  1       5    B      B     B
# 3  1       6    C      C     C
# 4  2       7    A      A     A
# 5  2       8    C      C     C


# get maximum number of rows for a single id
# this will help you get the wide format
max_num_rows = max((dt %>% count(id))$n)

# get names of columns to reshape
col_names = names(dt)[-1]

dt %>% 
group_by(id) %>% 
mutate(nrow = paste0("row",row_number())) %>%
unite_("V",col_names) %>%
spread(nrow, V) %>%
unite("z",matches("row")) %>%
separate(z, paste0(col_names, sort(rep(1:max_num_rows, ncol(dt)-1))), convert=T) %>%
ungroup()

# # A tibble: 2 × 13
#      id zipcode1 city1 county1 state1 zipcode2 city2 county2 state2 zipcode3 city3 county3 state3
# * <dbl>    <int> <chr>   <chr>  <chr>    <int> <chr>   <chr>  <chr>    <int> <chr>   <chr>  <chr>
# 1     1        4     A       A      A        5     B       B      B        6     C       C      C
# 2     2        7     A       A      A        8     C       C      C       NA  <NA>    <NA>   <NA>