根据列中的唯一值将数据框转换为 "ranked lists" 的矩阵

Convert data frame into a matrix of "ranked lists" based on unique values in column

假设我有一个如下所示的数据框 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

我想最终将其转换为 "ranked lists" 的矩阵,其行具有 entry 列中的唯一值,列数应等于 给定 entrypoint 列中唯一元素的最大 数量。在此示例中,它将是 3。每一行应使用 point 列中的相应值填充,并根据 value 中的相应元素降序排序(例如,行 A 应具有v2 作为第一列中的值)。如果 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

到目前为止,我已经尝试使用

创建某种应急措施table
with(df, table(df$point, df$entry))

但当然我的实际数据是数百万条目的顺序,即使在子集为 100 entries 和数百个独特的 points.我也试过

xtabs(~ entry + point, data=df)

在我的真实数据上得到相同的结果。接下来,我尝试使用

将其拆分为有序列表
df = split(df$point, df$entry)

工作正常而且速度足够快,buuuuut.. 现在我在将它转换为结果矩阵时遇到问题。大概是这样

matrix(sapply(df, function(x) unlist(x)), nrow=length(df), ncol=max(sapply(df, length)))

或者先初始化一个矩阵然后做一些rbind什么的?

res = matrix(NA, nrow=length(df), ncol=max(sapply(df, length)))
rownames(res) = names(df)
....

你能帮忙吗?

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   

考虑使用 by 条目 拆分并构建所需的向量。对于最终矩阵中相同长度的行,根据需要添加 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 

Rextester Demo