【问题标题】:How to turn values into variables and assign them a value according to their rank?如何将值变成变量并根据它们的等级给它们赋值?
【发布时间】:2020-08-16 18:18:19
【问题描述】:

给定这样的数据框:

df <- data.frame(ID = seq(1,8), 
rank1 = c("apple", "NA", "banana", "kiwi", "peach", "kiwi", "kiwi", "grape"), 
rank2 = c('mango', 'NA', 'date', 'grape', 'kiwi', 'apple', 'pear', 'NA'), 
rank3 = c('kiwi', 'NA', 'apple ', 'peach', 'banana', 'NA', 'mango', 'NA'))

ID  rank1 rank2  rank3  
1  1  apple mango   kiwi  
2  2     NA    NA     NA  
3  3 banana  date apple   
4  4   kiwi grape  peach  
5  5  peach  kiwi banana  
6  6   kiwi apple     NA

是否可以将值转换为变量并根据它们的等级分配一个值?

我想要这样的输出:

  ID apple mango  kiwi banana  date grape peach pear 
1  1 rank1 rank2 rank3     NA    NA    NA    NA   NA  
2  2    NA    NA    NA     NA    NA    NA    NA   NA  
3  3 rank3    NA    NA  rank1 rank2    NA    NA   NA  
4  4    NA    NA rank1     NA    NA rank2 rank3   NA  
5  5    NA    NA rank2  rank3    NA    NA rank1   NA  
6  6 rank2    NA rank1     NA    NA    NA    NA   NA

如何使用以下公式为排名位置分配权重:n-r+1(n = 标准数量,r = 排名位置)?

【问题讨论】:

  • 我看到了你的输入,也看到了你想要的输出,这一切看起来都很好,也很有意义。但是你说“如何使用公式为排名位置分配权重:n-r+1(n = 标准数量,r = 排名位置)?”,这不是有道理。这已经是您想要的输出的一部分,我看不到吗?或者您是否还有其他想要的输出没有显示?
  • 条件数是您的第二个数据集中的水果列数吗?
  • 我很抱歉描述不好。例如在第 3 行有 3 个水果排名,这是标准的数量。在这里,我会为“苹果”分配 3-3+1=1 的权重,为第 6 行分配 2-2+1=1 的权重。

标签: r dataframe dplyr ranking


【解决方案1】:

这是使用stack + reshape 的基本 R 选项

dfout <- reshape(
  subset(
    cbind(stack(df[-1]), id = df$ID),
    values != "NA"
  ),
  direction = "wide",
  idvar = "id",
  timevar = "values"
)

dfout <- setNames(dfout,gsub("ind\\.","",names(dfout)))

给了

   id apple banana  kiwi peach grape mango  date  pear apple
1  1 rank1   <NA> rank3  <NA>  <NA> rank2  <NA>  <NA>   <NA>
3  3  <NA>  rank1  <NA>  <NA>  <NA>  <NA> rank2  <NA>  rank3
4  4  <NA>   <NA> rank1 rank3 rank2  <NA>  <NA>  <NA>   <NA>
5  5  <NA>  rank3 rank2 rank1  <NA>  <NA>  <NA>  <NA>   <NA>
6  6 rank2   <NA> rank1  <NA>  <NA>  <NA>  <NA>  <NA>   <NA>
7  7  <NA>   <NA> rank1  <NA>  <NA> rank3  <NA> rank2   <NA>
8  8  <NA>   <NA>  <NA>  <NA> rank1  <NA>  <NA>  <NA>   <NA>

【讨论】:

    【解决方案2】:

    一种方法是从原始数据帧重塑为更长的格式,然后重塑为切换变量的宽格式。

    library(tidyr)
    library(dplyr)
    
    #pivot longer
    dfl <- pivot_longer(df, starts_with("rank"), names_to="rank", values_to = "fruit")
    
    #clean up data
    dfl$fruit <- trimws(dfl$fruit) 
    #dfl <- dfl[dfl$fruit != "NA",]  #optional
    
    #reshape wider
    pivot_wider(dfl, ID, names_from = "fruit", values_from = "rank", values_fn = first)
    # # A tibble: 8 x 10
    #    ID apple mango kiwi  `NA`  banana date  grape peach pear 
    # <int> <chr> <chr> <chr> <chr> <chr>  <chr> <chr> <chr> <chr>
    #     1     1 rank1 rank2 rank3 NA    NA     NA    NA    NA    NA   
    #     2     2 NA    NA    NA    rank1 NA     NA    NA    NA    NA   
    #     3     3 rank3 NA    NA    NA    rank1  rank2 NA    NA    NA   
    #     4     4 NA    NA    rank1 NA    NA     NA    rank2 rank3 NA   
    #     5     5 NA    NA    rank2 NA    rank3  NA    NA    rank1 NA   
    #     6     6 rank2 NA    rank1 rank3 NA     NA    NA    NA    NA   
    #     7     7 NA    rank3 rank1 NA    NA     NA    NA    NA    rank2
    #     8     8 NA    NA    NA    rank2 NA     NA    rank1 NA    NA    
    

    因为我在pivot_wider 函数中使用了first 函数。是选择第一个实例,以防 ID 中有多个,就像原始数据的第二行一样。

    注意:需要删除“NA”列。

    【讨论】:

      【解决方案3】:

      我相信这个 dplyr/tidyr 管道会计算 ranks 而不是问题中提到的 weights

      library(tidyverse)
      
      df %>%
        pivot_longer(
          cols = starts_with('rank'),
          names_to = 'rank',
          values_to = 'fruit'
        ) %>%
        mutate(rank = as.integer(sub('^rank', '', rank)),
               fruit = trimws(fruit)) %>%
        filter(!is.na(fruit), fruit != 'NA') %>%
        pivot_wider(
          id_cols = ID,
          names_from = fruit,
          values_from = rank
        )
      ## A tibble: 7 x 9
      #     ID apple mango  kiwi banana  date grape peach  pear
      #  <int> <int> <int> <int>  <int> <int> <int> <int> <int>
      #1     1     1     2     3     NA    NA    NA    NA    NA
      #2     3     3    NA    NA      1     2    NA    NA    NA
      #3     4    NA    NA     1     NA    NA     2     3    NA
      #4     5    NA    NA     2      3    NA    NA     1    NA
      #5     6     2    NA     1     NA    NA    NA    NA    NA
      #6     7    NA     3     1     NA    NA    NA    NA     2
      #7     8    NA    NA    NA     NA    NA     1    NA    NA
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 2021-06-25
        • 2023-03-19
        相关资源
        最近更新 更多