假设我有一个数据帧df
,看起来像这样:
df = data.frame(c("A", "A", "B", "B", "C", "D", "D", "D", "E"),
c(0.1, 0.3, 0.1, 0.8, 0.4, 0.7, 0.5, 0.2, 0.1),
c("v1", "v2", "v1", "v3", "v4", "v2", "v3", "v4", "v2"))
colnames(df) = c("entry", "value", "point")
df = df[order(df$entry, -df$value),]
df
entry value point
2 A 0.3 v2
1 A 0.1 v1
4 B 0.8 v3
3 B 0.1 v1
5 C 0.4 v4
6 D 0.7 v2
7 D 0.5 v3
8 D 0.2 v4
9 E 0.1 v2
我想最终将其转换为“排序列表”矩阵,该矩阵在entry
列中具有唯一值,并且列数应等于最大给定point
的{{1}}列中的strong>个唯一元素。在此示例中为3。每行应填充entry
列中的相应值,并根据point
中的相应元素进行降序排序(例如,行value
应该具有A
作为第一列中的值)。如果v2
的{{1}}少于矩阵中的列数,则该行的其余部分应填充entry
。
因此,预期输出应如下所示:
points
到目前为止,我已经尝试使用
创建某种列联表NAs
但是我的实际数据当然是上百万个条目的顺序,并且即使用数百个唯一的>df
1 2 3
A v2 v1 NA
B v3 v1 NA
C v4 NA NA
D v2 v3 v4
E v2 NA NA
设置为100 with(df, table(df$point, df$entry))
时,上述命令也会产生大量的RAM。我也尝试过
entries
在我的真实数据上具有相同的结果。接下来,我尝试使用
将其拆分为有序列表points
它可以正常工作并且足够快,buuuuut ..现在我在将其转换为结果矩阵时遇到问题。大概是这样
xtabs(~ entry + point, data=df)
还是首先初始化一个矩阵,然后做一些df = split(df$point, df$entry)
之类的事情?
matrix(sapply(df, function(x) unlist(x)), nrow=length(df), ncol=max(sapply(df, length)))
可以请您帮忙吗?
答案 0 :(得分:2)
使用dplyr
:
df %>%
group_by(entry) %>%
mutate(unq=rank(rev(value))) %>%
select(-value) %>%
tidyr::spread(unq,point)
# A tibble: 5 x 4
# Groups: entry [5]
entry `1` `2` `3`
<fct> <fct> <fct> <fct>
1 A v2 v1 NA
2 B v3 v1 NA
3 C v4 NA NA
4 D v2 v3 v4
5 E v2 NA NA
答案 1 :(得分:1)
考虑使用by
按 entry 进行拆分并构建所需的向量。对于最终矩阵中相同长度的行,根据需要添加NA
,其中下面的3
可以更改为任意多的列。
vec_list <- by(df, df$entry, function(sub) {
vec <- as.character(sub[order(-sub$value),]$point)
c(vec, rep(NA, 3 - length(vec)))
})
final_matrix <- do.call(rbind, vec_list)
final_matrix
# [,1] [,2] [,3]
# A "v2" "v1" NA
# B "v3" "v1" NA
# C "v4" NA NA
# D "v2" "v3" "v4"
# E "v2" NA NA