仅使用 reshape(base) 将宽数据重塑为面板并将字符串保留为时间序列标识符
Reshaping wide data to panel using reshape(base) only and keeping strings as time series identifiers
我有一个类似于以下摘录的数据集:
set.seed(1)
df <- data.frame(geography=rep(c(LETTERS),3),December.1999 = runif(n=78),
January.2000 = runif(n=78),March.2000 = runif(n=78),
April.2000 = runif(n=78), February.2001 = runif(n=78))
我的目的是获得类似于以下格式的长数据集:
geography time value
A December.1999 0.26550866
A January.2000 0.77732070
目前,我正在使用以下代码:
df_r <- reshape(df, varying = names(df)[2:length(df)], direction = "long",
v.names = "Value")
产生
geography time Value Geography
1.1 A 1 0.2655087 1
2.1 B 1 0.3721239 2
3.1 C 1 0.5728534 3
4.1 D 1 0.9082078 4
5.1 E 1 0.2016819 5
6.1 F 1 0.8983897 6
我想要构建的数据集在 time 列中具有列名:
geography time Value
A.December.199 A December.1999 0.2655087
... ... ... ...
并且会满足以下品质:
- 行名对应地理名+日期列名
- 时间列 将存储为具有确切列名的章程
- value 列将包含数字,但也包含任何可能的字符串和
NAs
无意中可能出现在真实数据中
我不是在寻找利用 reshape2
、dplyr
或任何其他附加包的解决方案。我想使用 R Stats 包中可用的 reshape
来实现这个简单的转换。
使用base R
方法,我们可以unlist
除第一列之外的列来创建'value'列。通过使用data.frame
,我们可以根据unlist
个元素的长度得到'geography'列进行回收。如果我们需要根据列名创建一个'time'列,我们可以通过数据集的nrow
复制列名。在这里,我使用了一个方便的包装器 col
,它为要复制的列提供了数字索引。
res <- data.frame(geography=df$geography, time=colnames(df)[-1][col(df[-1])],
value=unlist(df[-1]))
res1 <- res[order(res$geography),]
row.names(res1) <- NULL
head(res1,3)
# geography time value
#1 A December.1999 0.26550866
#2 A December.1999 0.01339033
#3 A December.1999 0.43809711
或者使用reshape
(OP代码中的'df_r'),我们可以使用'time'中的数字索引将这些值替换为'df'[的列名=24=]
df_r$time <- colnames(df)[-1][df_r$time]
res2 <- df_r[order(df_r$geography),-4]
row.names(res2) <- NULL
head(res2,3)
# geography time Value
#1 A December.1999 0.26550866
#2 A December.1999 0.01339033
#3 A December.1999 0.43809711
如果我们需要在 reshape
内执行此操作,我们可以指定 times
。默认情况下,它是 times = seq_along(varying[[1]])
(?reshape
).
df_r <- reshape(df, varying=names(df)[2:length(df)], times=names(df)[-1],
direction='long', v.names='Value')
res3 <- df_r[order(df_r$geography),-4]
row.names(res3) <- NULL
head(res3,3)
# geography time Value
#1 A December.1999 0.26550866
#2 A December.1999 0.01339033
#3 A December.1999 0.43809711
我有一个类似于以下摘录的数据集:
set.seed(1)
df <- data.frame(geography=rep(c(LETTERS),3),December.1999 = runif(n=78),
January.2000 = runif(n=78),March.2000 = runif(n=78),
April.2000 = runif(n=78), February.2001 = runif(n=78))
我的目的是获得类似于以下格式的长数据集:
geography time value
A December.1999 0.26550866
A January.2000 0.77732070
目前,我正在使用以下代码:
df_r <- reshape(df, varying = names(df)[2:length(df)], direction = "long",
v.names = "Value")
产生
geography time Value Geography
1.1 A 1 0.2655087 1
2.1 B 1 0.3721239 2
3.1 C 1 0.5728534 3
4.1 D 1 0.9082078 4
5.1 E 1 0.2016819 5
6.1 F 1 0.8983897 6
我想要构建的数据集在 time 列中具有列名:
geography time Value
A.December.199 A December.1999 0.2655087
... ... ... ...
并且会满足以下品质:
- 行名对应地理名+日期列名
- 时间列 将存储为具有确切列名的章程
- value 列将包含数字,但也包含任何可能的字符串和
NAs
无意中可能出现在真实数据中
我不是在寻找利用 reshape2
、dplyr
或任何其他附加包的解决方案。我想使用 R Stats 包中可用的 reshape
来实现这个简单的转换。
使用base R
方法,我们可以unlist
除第一列之外的列来创建'value'列。通过使用data.frame
,我们可以根据unlist
个元素的长度得到'geography'列进行回收。如果我们需要根据列名创建一个'time'列,我们可以通过数据集的nrow
复制列名。在这里,我使用了一个方便的包装器 col
,它为要复制的列提供了数字索引。
res <- data.frame(geography=df$geography, time=colnames(df)[-1][col(df[-1])],
value=unlist(df[-1]))
res1 <- res[order(res$geography),]
row.names(res1) <- NULL
head(res1,3)
# geography time value
#1 A December.1999 0.26550866
#2 A December.1999 0.01339033
#3 A December.1999 0.43809711
或者使用reshape
(OP代码中的'df_r'),我们可以使用'time'中的数字索引将这些值替换为'df'[的列名=24=]
df_r$time <- colnames(df)[-1][df_r$time]
res2 <- df_r[order(df_r$geography),-4]
row.names(res2) <- NULL
head(res2,3)
# geography time Value
#1 A December.1999 0.26550866
#2 A December.1999 0.01339033
#3 A December.1999 0.43809711
如果我们需要在 reshape
内执行此操作,我们可以指定 times
。默认情况下,它是 times = seq_along(varying[[1]])
(?reshape
).
df_r <- reshape(df, varying=names(df)[2:length(df)], times=names(df)[-1],
direction='long', v.names='Value')
res3 <- df_r[order(df_r$geography),-4]
row.names(res3) <- NULL
head(res3,3)
# geography time Value
#1 A December.1999 0.26550866
#2 A December.1999 0.01339033
#3 A December.1999 0.43809711