根据列

时间:2019-01-03 14:10:14

标签: r dataframe matrix ranking

假设我有一个数据帧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)))

可以请您帮忙吗?

2 个答案:

答案 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 

Rextester Demo