如何重塑我的数据,将行移动到新列?
How can I reshape my data, moving rows to new columns?
我知道我的问题很简单,但是现在我正在学习如何以不同的方式重塑数据,所以请理解。
我有这样的数据:
Input = (
'col1 col2
A 2
B 4
A 7
B 3
A 4
B 2
A 4
B 6
A 3
B 3')
df = read.table(textConnection(Input), header = T)
> df
col1 col2
1 A 2
2 B 4
3 A 7
4 B 3
5 A 4
6 B 2
7 A 4
8 B 6
9 A 3
10 B 3
我想要这样的东西,其中列名并不重要:
col1 v1 v2 v3 v4 v5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
到目前为止,我做了类似的事情:
res_1 <- aggregate(col2 ~., df, toString)
col1 col2
1 A 2, 7, 4, 4, 3
2 B 4, 3, 2, 6, 3
它确实有效,但是,我有一个列并且值是用逗号分隔的,而不是在新列中,所以我决定修复它:
res_2 <- do.call("rbind", strsplit(res_1$col2, ","))
[,1] [,2] [,3] [,4] [,5]
[1,] "2" " 7" " 4" " 4" " 3"
[2,] "4" " 3" " 2" " 6" " 3"
最后合并它并删除不需要的列:
final <- cbind(res_1,res_2)
final$col2 <- NULL
col1 1 2 3 4 5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
所以我得到了我想要的输出,但我对这个方法不满意,我确信有一个简单而简短的命令可以做到这一点。正如我所说,我想使用不同的包来学习新的更优雅的选项。
谢谢!
你可以简单地做,
do.call(rbind, split(df$col2, df$col1))
# [,1] [,2] [,3] [,4] [,5]
#A 2 7 4 4 3
#B 4 3 2 6 3
您可以将其包装到 data.frame()
以从矩阵转换为 df
问题用 reshape2 和 reshape
标记,因此我们展示了该包和基础 reshape
函数的使用。还说明了 dplyr/tidyr 的用法。最后,我们展示了一个 data.table 解决方案和一个使用 xtabs
.
的第二个基本 R 解决方案
reshape2添加组列,然后从长格式转换为宽格式:
library(reshape2)
df2 <- transform(df, group = paste0("v", ave(1:nrow(df), col1, FUN = seq_along)))
dcast(df2, col1 ~ group, value.var = "col2")
给予:
col1 v1 v2 v3 v4 v5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
2) reshape 使用 (1) 中的 df2
我们使用 reshape
函数得到以下基本 R 解决方案:
wide <- reshape(df2, dir = "wide", idvar = "col1", timevar = "group")
names(wide) <- sub(".*\.", "", names(wide))
wide
给予:
col1 v1 v2 v3 v4 v5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
3) dplyr/tidyr
library(dplyr)
library(tidyr)
df %>%
group_by(col1) %>%
mutate(group = paste0("v", row_number())) %>%
ungroup %>%
pivot_wider(names_from = "group", values_from = "col2")
给予:
# A tibble: 2 x 6
col1 v1 v2 v3 v4 v5
<fct> <int> <int> <int> <int> <int>
1 A 2 7 4 4 3
2 B 4 3 2 6 3
4) data.table
library(data.table)
as.data.table(df)[, as.list(col2), by = col1]
给予:
col1 V1 V2 V3 V4 V5
1: A 2 7 4 4 3
2: B 4 3 2 6 3
5) xtabs 另一个基础 R 解决方案使用来自 (1) 和 xtabs
的 df2。这会产生一个 class c("xtabs", "table")` 的对象。请注意,它标记了尺寸。
xtabs(col2 ~., df2)
给予:
group
col1 v1 v2 v3 v4 v5
A 2 7 4 4 3
B 4 3 2 6 3
我知道我的问题很简单,但是现在我正在学习如何以不同的方式重塑数据,所以请理解。
我有这样的数据:
Input = (
'col1 col2
A 2
B 4
A 7
B 3
A 4
B 2
A 4
B 6
A 3
B 3')
df = read.table(textConnection(Input), header = T)
> df
col1 col2
1 A 2
2 B 4
3 A 7
4 B 3
5 A 4
6 B 2
7 A 4
8 B 6
9 A 3
10 B 3
我想要这样的东西,其中列名并不重要:
col1 v1 v2 v3 v4 v5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
到目前为止,我做了类似的事情:
res_1 <- aggregate(col2 ~., df, toString)
col1 col2
1 A 2, 7, 4, 4, 3
2 B 4, 3, 2, 6, 3
它确实有效,但是,我有一个列并且值是用逗号分隔的,而不是在新列中,所以我决定修复它:
res_2 <- do.call("rbind", strsplit(res_1$col2, ","))
[,1] [,2] [,3] [,4] [,5]
[1,] "2" " 7" " 4" " 4" " 3"
[2,] "4" " 3" " 2" " 6" " 3"
最后合并它并删除不需要的列:
final <- cbind(res_1,res_2)
final$col2 <- NULL
col1 1 2 3 4 5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
所以我得到了我想要的输出,但我对这个方法不满意,我确信有一个简单而简短的命令可以做到这一点。正如我所说,我想使用不同的包来学习新的更优雅的选项。 谢谢!
你可以简单地做,
do.call(rbind, split(df$col2, df$col1))
# [,1] [,2] [,3] [,4] [,5]
#A 2 7 4 4 3
#B 4 3 2 6 3
您可以将其包装到 data.frame()
以从矩阵转换为 df
问题用 reshape2 和 reshape
标记,因此我们展示了该包和基础 reshape
函数的使用。还说明了 dplyr/tidyr 的用法。最后,我们展示了一个 data.table 解决方案和一个使用 xtabs
.
reshape2添加组列,然后从长格式转换为宽格式:
library(reshape2)
df2 <- transform(df, group = paste0("v", ave(1:nrow(df), col1, FUN = seq_along)))
dcast(df2, col1 ~ group, value.var = "col2")
给予:
col1 v1 v2 v3 v4 v5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
2) reshape 使用 (1) 中的 df2
我们使用 reshape
函数得到以下基本 R 解决方案:
wide <- reshape(df2, dir = "wide", idvar = "col1", timevar = "group")
names(wide) <- sub(".*\.", "", names(wide))
wide
给予:
col1 v1 v2 v3 v4 v5
1 A 2 7 4 4 3
2 B 4 3 2 6 3
3) dplyr/tidyr
library(dplyr)
library(tidyr)
df %>%
group_by(col1) %>%
mutate(group = paste0("v", row_number())) %>%
ungroup %>%
pivot_wider(names_from = "group", values_from = "col2")
给予:
# A tibble: 2 x 6
col1 v1 v2 v3 v4 v5
<fct> <int> <int> <int> <int> <int>
1 A 2 7 4 4 3
2 B 4 3 2 6 3
4) data.table
library(data.table)
as.data.table(df)[, as.list(col2), by = col1]
给予:
col1 V1 V2 V3 V4 V5
1: A 2 7 4 4 3
2: B 4 3 2 6 3
5) xtabs 另一个基础 R 解决方案使用来自 (1) 和 xtabs
的 df2。这会产生一个 class c("xtabs", "table")` 的对象。请注意,它标记了尺寸。
xtabs(col2 ~., df2)
给予:
group
col1 v1 v2 v3 v4 v5
A 2 7 4 4 3
B 4 3 2 6 3