重塑异常数据集
Reshaping unusual data set
我有 运行 进入一个不寻常的数据集,我需要重新整形,但正常的 reshape/tidyr 包似乎没有办法解决它。虽然可以使用子集和 rbind 重塑数据集,但必须有更直接的方法来解决这个问题。
数据集是这样的:
ID Item.1 Item.1.Value Item.2 Item.2.Value Item.3 Item.3.Value
001 A 3 C 7
002 B 4
003 A 2 B 1 F 5
004 C 10 L 3
每个观察包含 20 个测量值集合中的 1-3 个测量值。此外,相同的测量类型可以出现在不同观察的多个列中。
我要改成这样:
ID Item Item.Value
001 A 3
001 C 7
002 B 4
003 A 2
003 B 1
003 F 5
004 C 10
004 L 3
我的部分问题是我不知道初始配置的常规术语 table。
谢谢!
我不会称它为 "unusual" 数据集,但增加额外复杂度的是 ID
列之后,其余列都是 Item-Value对。以下是使用基本 reshape
和 tidyverse
函数将数据从 "wide" 格式重塑为 "long" 格式的方法。
为了可重复性,这里是我开始使用的数据框:
df = structure(list(ID = c("001", "002", "003", "004"), Item.1 = structure(c(1L,
2L, 1L, 3L), .Label = c("A", "B", "C"), class = "factor"), Item.1.Value = c(3L,
4L, 2L, 10L), Item.2 = structure(c(3L, 1L, 2L, 4L), .Label = c("",
"B", "C", "L"), class = "factor"), Item.2.Value = c(7L, NA, 1L,
3L), Item.3 = c(NA, NA, "F", NA), Item.3.Value = c(NA, NA, 5L,
NA)), .Names = c("ID", "Item.1", "Item.1.Value", "Item.2", "Item.2.Value",
"Item.3", "Item.3.Value"), row.names = c(NA, -4L), class = "data.frame")
基础reshape
方法
dfr = reshape(df, varying=list(seq(2,ncol(df),2),seq(3,ncol(df),2)), direction="long",
idvar="ID", timevar=NULL, v.names=c("Item","Value"))
dfr = dfr[!is.na(dfr$Value),]
dfr = dfr[order(dfr$ID),]
dfr
ID Item Value
001.1 001 A 3
001.2 001 C 7
002.1 002 B 4
003.1 003 A 2
003.2 003 B 1
003.3 003 F 5
004.1 004 C 10
004.2 004 L 3
tidyverse
方法
我不确定这是否是最简洁或优雅的方法,所以如果您有更好的方法,请告诉我。
library(tidyverse)
dfr = map2_df(seq(2,ncol(df),2), seq(3,ncol(df),2),
~ setNames(df[, c(1,.x,.y)], c("ID","Item","Value"))) %>%
filter(!is.na(Value)) %>%
arrange(ID)
ID Item Value
1 001 A 3
2 001 C 7
3 002 B 4
4 003 A 2
5 003 B 1
6 003 F 5
7 004 C 10
8 004 L 3
我有 运行 进入一个不寻常的数据集,我需要重新整形,但正常的 reshape/tidyr 包似乎没有办法解决它。虽然可以使用子集和 rbind 重塑数据集,但必须有更直接的方法来解决这个问题。
数据集是这样的:
ID Item.1 Item.1.Value Item.2 Item.2.Value Item.3 Item.3.Value
001 A 3 C 7
002 B 4
003 A 2 B 1 F 5
004 C 10 L 3
每个观察包含 20 个测量值集合中的 1-3 个测量值。此外,相同的测量类型可以出现在不同观察的多个列中。
我要改成这样:
ID Item Item.Value
001 A 3
001 C 7
002 B 4
003 A 2
003 B 1
003 F 5
004 C 10
004 L 3
我的部分问题是我不知道初始配置的常规术语 table。
谢谢!
我不会称它为 "unusual" 数据集,但增加额外复杂度的是 ID
列之后,其余列都是 Item-Value对。以下是使用基本 reshape
和 tidyverse
函数将数据从 "wide" 格式重塑为 "long" 格式的方法。
为了可重复性,这里是我开始使用的数据框:
df = structure(list(ID = c("001", "002", "003", "004"), Item.1 = structure(c(1L,
2L, 1L, 3L), .Label = c("A", "B", "C"), class = "factor"), Item.1.Value = c(3L,
4L, 2L, 10L), Item.2 = structure(c(3L, 1L, 2L, 4L), .Label = c("",
"B", "C", "L"), class = "factor"), Item.2.Value = c(7L, NA, 1L,
3L), Item.3 = c(NA, NA, "F", NA), Item.3.Value = c(NA, NA, 5L,
NA)), .Names = c("ID", "Item.1", "Item.1.Value", "Item.2", "Item.2.Value",
"Item.3", "Item.3.Value"), row.names = c(NA, -4L), class = "data.frame")
基础reshape
方法
dfr = reshape(df, varying=list(seq(2,ncol(df),2),seq(3,ncol(df),2)), direction="long",
idvar="ID", timevar=NULL, v.names=c("Item","Value"))
dfr = dfr[!is.na(dfr$Value),]
dfr = dfr[order(dfr$ID),]
dfr
ID Item Value 001.1 001 A 3 001.2 001 C 7 002.1 002 B 4 003.1 003 A 2 003.2 003 B 1 003.3 003 F 5 004.1 004 C 10 004.2 004 L 3
tidyverse
方法
我不确定这是否是最简洁或优雅的方法,所以如果您有更好的方法,请告诉我。
library(tidyverse)
dfr = map2_df(seq(2,ncol(df),2), seq(3,ncol(df),2),
~ setNames(df[, c(1,.x,.y)], c("ID","Item","Value"))) %>%
filter(!is.na(Value)) %>%
arrange(ID)
ID Item Value 1 001 A 3 2 001 C 7 3 002 B 4 4 003 A 2 5 003 B 1 6 003 F 5 7 004 C 10 8 004 L 3