在大多数列具有多个值的地方从长到宽重塑
Reshape long to wide where most columns have multiple values
我有如下数据:
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
我有一个邮政编码列表、它们包含的城市以及它们所在的 counties/states。IDnum = 县和州的组合数值。列表是你现在看到的格式,我需要将它从长到宽/垂直到水平,其中 IDnum 变量成为唯一标识符,所有其他可能的值组合成为宽变量。
IDnum zip1 city1 county1 state1 zip2 city2 county2
10011 36006 Billingsley Autauga AL 36022 Deatsville Autauga
这只是数据集的样本,它涵盖了美国的每个邮编并包含更多变量。我见过与此类似的其他问题和答案,但几乎每一列都没有多个值。
SPSS 和 STATA 中的命令会以这种方式重塑数据,在 SPSS 中我可以 运行 一个 Restructure/Cases 到 Vars 命令,将我初始数据集中的 11 个变量变成大约 1750,b/c 一个县有超过 290 个 zips,它复制了大多数其他变量 290 多次。这会产生很多空白,但我需要将其重新整形为一个非常长的水平文件。
我查看了 reshape 和 reshape2,但被 'default to length' 错误消息挂断了。我确实得到了 melt/dcast 来排序,但这会创建一个变量,它是所有值的列表,而不是为每个值创建变量。
melted_dupes <- melt(zip_code_list_dupes, id.vars= c("IDnum"))
HRZ_dupes <- dcast(melted_dupes, IDnum ~ variable, fun.aggregate = list)
我已经尝试过 tidyr 和 dplyr,但在语法上迷失了方向。有点惊讶没有类似于其他包中内置命令的数据命令,让我假设有,但我还没有弄明白。
感谢任何帮助。
可能有更有效的方法,但请尝试以下方法。
我使用了我自己的(示例)数据集,与您的数据集非常相似。
运行 逐步了解其工作原理,因为您必须修改代码中的某些内容。
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>
您可以在按 IDnum
添加连续计数后使用基本函数 reshape
执行此操作。假设您的数据存储在名为 df
:
的 data.frame
中
df2 <- within(df, count <- ave(rep(1,nrow(df)),df$IDnum,FUN=cumsum))
提供名为 "time" 的连续计数的新列。现在我们可以 reshape
到宽格式
reshape(df2,direction="wide",idvar="IDnum",timevar="count")
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,等等)
我有如下数据:
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
我有一个邮政编码列表、它们包含的城市以及它们所在的 counties/states。IDnum = 县和州的组合数值。列表是你现在看到的格式,我需要将它从长到宽/垂直到水平,其中 IDnum 变量成为唯一标识符,所有其他可能的值组合成为宽变量。
IDnum zip1 city1 county1 state1 zip2 city2 county2
10011 36006 Billingsley Autauga AL 36022 Deatsville Autauga
这只是数据集的样本,它涵盖了美国的每个邮编并包含更多变量。我见过与此类似的其他问题和答案,但几乎每一列都没有多个值。
SPSS 和 STATA 中的命令会以这种方式重塑数据,在 SPSS 中我可以 运行 一个 Restructure/Cases 到 Vars 命令,将我初始数据集中的 11 个变量变成大约 1750,b/c 一个县有超过 290 个 zips,它复制了大多数其他变量 290 多次。这会产生很多空白,但我需要将其重新整形为一个非常长的水平文件。
我查看了 reshape 和 reshape2,但被 'default to length' 错误消息挂断了。我确实得到了 melt/dcast 来排序,但这会创建一个变量,它是所有值的列表,而不是为每个值创建变量。
melted_dupes <- melt(zip_code_list_dupes, id.vars= c("IDnum"))
HRZ_dupes <- dcast(melted_dupes, IDnum ~ variable, fun.aggregate = list)
我已经尝试过 tidyr 和 dplyr,但在语法上迷失了方向。有点惊讶没有类似于其他包中内置命令的数据命令,让我假设有,但我还没有弄明白。
感谢任何帮助。
可能有更有效的方法,但请尝试以下方法。 我使用了我自己的(示例)数据集,与您的数据集非常相似。 运行 逐步了解其工作原理,因为您必须修改代码中的某些内容。
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>
您可以在按 IDnum
添加连续计数后使用基本函数 reshape
执行此操作。假设您的数据存储在名为 df
:
data.frame
中
df2 <- within(df, count <- ave(rep(1,nrow(df)),df$IDnum,FUN=cumsum))
提供名为 "time" 的连续计数的新列。现在我们可以 reshape
到宽格式
reshape(df2,direction="wide",idvar="IDnum",timevar="count")
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,等等)