使用 id 变量重复的分组重塑 data.frame
Reshaping data.frame with a by-group where id variable repeats
我想重塑/重新排列数据集,该数据集存储为 data.frame 两列:
- id(非唯一,即可以重复多行)--> 存储为字符
- 值 --> 存储为数值(范围 1:3)
示例数据:
id <- as.character(1001:1003)
val_list <- data.frame(sample(1:3, size=12, replace=TRUE))
have <- data.frame(cbind(rep(id, 4), val_list))
colnames(have) <- c("id", "values")
have <- have %>% arrange(id)
这给了我以下输出:
id values
1 1001 2
2 1001 2
3 1001 2
4 1001 3
5 1002 2
6 1002 3
7 1002 2
8 1002 2
9 1003 1
10 1003 3
11 1003 1
12 1003 2
我想要的:
want <- data.frame(cbind(have[1:4, 2],
have[5:8, 2],
have[9:12, 2]))
colnames(want) <- id
想要输出:
1001 1002 1003
1 2 2 1
2 2 3 3
3 2 2 1
4 3 2 2
我的原始数据集有 >1000 个变量 "id" 和 >50 个变量 "value"。
我想对数据集进行分块/切片得到一个新的 data.frame,其中每个 "id" 变量将代表一列列出其 "value" 变量内容。
可以通过循环来解决,但我想要矢量化解决方案。
如果可能,将基数 R 作为 "one-liner",但其他解决方案也很受欢迎。
您可以为每个 id
创建一个唯一的行值并使用 pivot_wider
。
have %>%
group_by(id) %>%
mutate(row = row_number()) %>%
tidyr::pivot_wider(names_from = id, values_from = values) %>%
select(-row)
# A tibble: 4 x 3
# `1001` `1002` `1003`
# <int> <int> <int>
#1 1 3 1
#2 3 2 3
#3 2 2 3
#4 2 2 3
或使用 data.table
library(data.table)
dcast(setDT(have), rowid(id)~id, value.var = 'values')
数据
df <- structure(list(id = c(1001L, 1001L, 1001L, 1001L, 1002L, 1002L,
1002L, 1002L, 1003L, 1003L, 1003L, 1003L), values = c(2L, 2L,
2L, 3L, 2L, 3L, 2L, 2L, 1L, 3L, 1L, 2L)), class = "data.frame",
row.names = c(NA, -12L))
我想重塑/重新排列数据集,该数据集存储为 data.frame 两列:
- id(非唯一,即可以重复多行)--> 存储为字符
- 值 --> 存储为数值(范围 1:3)
示例数据:
id <- as.character(1001:1003)
val_list <- data.frame(sample(1:3, size=12, replace=TRUE))
have <- data.frame(cbind(rep(id, 4), val_list))
colnames(have) <- c("id", "values")
have <- have %>% arrange(id)
这给了我以下输出:
id values
1 1001 2
2 1001 2
3 1001 2
4 1001 3
5 1002 2
6 1002 3
7 1002 2
8 1002 2
9 1003 1
10 1003 3
11 1003 1
12 1003 2
我想要的:
want <- data.frame(cbind(have[1:4, 2],
have[5:8, 2],
have[9:12, 2]))
colnames(want) <- id
想要输出:
1001 1002 1003
1 2 2 1
2 2 3 3
3 2 2 1
4 3 2 2
我的原始数据集有 >1000 个变量 "id" 和 >50 个变量 "value"。 我想对数据集进行分块/切片得到一个新的 data.frame,其中每个 "id" 变量将代表一列列出其 "value" 变量内容。
可以通过循环来解决,但我想要矢量化解决方案。 如果可能,将基数 R 作为 "one-liner",但其他解决方案也很受欢迎。
您可以为每个 id
创建一个唯一的行值并使用 pivot_wider
。
have %>%
group_by(id) %>%
mutate(row = row_number()) %>%
tidyr::pivot_wider(names_from = id, values_from = values) %>%
select(-row)
# A tibble: 4 x 3
# `1001` `1002` `1003`
# <int> <int> <int>
#1 1 3 1
#2 3 2 3
#3 2 2 3
#4 2 2 3
或使用 data.table
library(data.table)
dcast(setDT(have), rowid(id)~id, value.var = 'values')
数据
df <- structure(list(id = c(1001L, 1001L, 1001L, 1001L, 1002L, 1002L,
1002L, 1002L, 1003L, 1003L, 1003L, 1003L), values = c(2L, 2L,
2L, 3L, 2L, 3L, 2L, 2L, 1L, 3L, 1L, 2L)), class = "data.frame",
row.names = c(NA, -12L))