【问题标题】:Recode column based on two other vectors根据其他两个向量重新编码列
【发布时间】:2019-10-30 22:12:12
【问题描述】:

这是我的数据集:

df = structure(list(from = c(0, 0, 0, 0, 38, 43, 49, 54), to = c(43, 
54, 56, 62, 62, 62, 62, 62), count = c(342, 181, 194, 386, 200, 
480, 214, 176), group = c("keiner", "keiner", "keiner", "keiner", 
"paid", "paid", "owned", "earned")), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -8L))

我的问题是fromto 列需要排名(必须对fromto 两列进行排名),因为可视化库需要并且还需要从索引 0 开始。 这就是我构建两个向量的原因,一个 (ranking) 对两列的每个唯一值进行排名,另一个 (uniquevalues) 使用数据集的原始唯一值。

ranking <- dplyr::dense_rank(unique(c(df$from, df$to))) - 1 ### Start Index at 0, "recode" variables
uniquevalues <- unique(c(df$from, df$to))

现在我必须重新编码原始数据集。 tofrom 列必须根据uniquevalues 的对应值接收来自ranking 的值。

我想到的唯一选择是创建两个向量的数据框并循环遍历每一行,但我真的很想为此提供一个向量化的解决方案。谁能帮帮我?

这个:

  <dbl> <dbl> <dbl> <chr> 
1     0    43   342 keiner
2     0    54   181 keiner
3     0    56   194 keiner
4     0    62   386 keiner
5    38    62   200 paid  
6    43    62   480 paid  
7    49    62   214 owned 
8    54    62   176 earned

应该变成这样:

   from    to count group 
  <dbl> <dbl> <dbl> <chr> 
1     0     2   342 keiner
2     0     4   181 keiner
3     0     5   194 keiner
4     0     6   386 keiner
5     1     6   200 paid  
6     2     6   480 paid  
7     3     6   214 owned 
8     4     6   176 earned

【问题讨论】:

  • 更新了我的帖子。这些帖子并没有真正帮助我,已经搜索了答案。

标签: r dplyr rank


【解决方案1】:

转换为因子并返回的另一种解决方案。

f <- unique(unlist(df1[1:2]))

df[1:2] <- lapply(df[1:2], function(x) {
  as.integer(as.character(factor(x, levels=f, labels=1:length(f) - 1)))
  })
df
# # A tibble: 8 x 4
#  from    to  count group 
# <fct> <fct> <dbl> <chr> 
# 1   0     2    342 keiner
# 2   0     4    181 keiner
# 3   0     5    194 keiner
# 4   0     6    386 keiner
# 5   1     6    200 paid  
# 6   2     6    480 paid  
# 7   3     6    214 owned 
# 8   4     6    176 earned

【讨论】:

    【解决方案2】:

    我会使用mapvalues 函数。像这样

    library(plyr)
    df[ , 1:2] <- mapvalues(unlist(df[ , 1:2]),
                            from= uniquevalues,
                            to= ranking)
    df
    #   from    to count group 
    #  <dbl> <dbl> <dbl> <chr> 
    #1     0     2   342 keiner
    #2     0     4   181 keiner
    #3     0     5   194 keiner
    #4     0     6   386 keiner
    #5     1     6   200 paid  
    #6     2     6   480 paid  
    #7     3     6   214 owned 
    #8     4     6   176 earned
    

    【讨论】:

      【解决方案3】:

      我们可以unlist 值和match 它们与uniquevalues

      df[1:2] <- match(unlist(df[1:2]), uniquevalues) - 1
      
      df
      
      #   from    to count group 
      #  <dbl> <dbl> <dbl> <chr> 
      #1     0     2   342 keiner
      #2     0     4   181 keiner
      #3     0     5   194 keiner
      #4     0     6   386 keiner
      #5     1     6   200 paid  
      #6     2     6   480 paid  
      #7     3     6   214 owned 
      #8     4     6   176 earned
      

      或者使用列名代替索引。

      df[c("from", "to")] <- match(unlist(df[c("from", "to")]), uniquevalues) - 1
      

      【讨论】:

      • 我认为这里的关键见解与 match 关系不大,而是与 R 将重塑原子向量以适应多个数据帧列的事实有关,只要总和列长度​​等于向量长度。结果是对 OP 原始代码的一些细微更改将产生相同的结果:df[1:2] &lt;- dense_rank(c(df$from, df$to)) - 1.
      猜你喜欢
      • 1970-01-01
      • 2022-09-23
      • 2021-01-28
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 2023-01-19
      • 2019-02-27
      • 1970-01-01
      相关资源
      最近更新 更多