【问题标题】:Create column with dplyr based on value and also frequency of another column, in R在 R 中,根据值和另一列的频率创建具有 dplyr 的列
【发布时间】:2018-12-07 22:21:03
【问题描述】:

当我想出一个更好的标题时,我会尽快编辑帖子名称,但目前,下面的一个简短示例突出了我正在努力解决的问题:

dput(mydf)
structure(list(gameID = c("34", "34", "34", "34", "34", "25", 
"25", "25")), class = "data.frame", row.names = c(NA, -8L))

mydf
    gameID
1     34
2     34
3     34
4     34
5     34
6     25
7     25
8     25

(仅包含 garbocCol 以便数据框具有 >1 列 - 否则请忽略。)这感觉应该是一个相当简单的数据操作问题。我想创建一个新列,它只是粘贴了该游戏ID 计数的游戏ID 列。因此,我正在寻找以下输出:

mydf
  gameID    newCol
1     34     34-1
2     34     34-2
3     34     34-3
4     34     34-4
5     34     34-5
6     25     25-1
7     25     25-2
8     25     25-3

gameID 列已经是一个字符,newCol 最好也是类型字符。我在一个很长的 dplyr 链中工作,并试图让以下工作:

mydf <- mydf %>% 
  dplyr::mutate(newCol = paste0(gameID, '-', {what goes here}))

我可以很容易地使用 for 循环来做到这一点,但是 dplyr 解决方案会好得多。

【问题讨论】:

  • 我应该删除 garbocol 它让帖子更加混乱

标签: r dplyr data-manipulation


【解决方案1】:

如果我们需要paste 和序列,获取row_number() 按'gameID' 和paste 分组的序列来创建'newCol'

mydf %>%
    group_by(gameID) %>%
    mutate(newCol = paste(gameID, row_number(), sep = '-'))
# A tibble: 8 x 3
# Groups:   gameID [2]
#  gameID garboCol newCol
#  <fct>     <dbl> <chr> 
#1 34            1 34-1  
#2 34            2 34-2  
#3 34            3 34-3  
#4 34            4 34-4  
#5 34            5 34-5  
#6 25            6 25-1  
#7 25            7 25-2  
#8 25            8 25-3  

如果我们想让这个更短,一个选项是rowid from data.table。优点是它不会在输出中创建组属性

library(data.table)
mydf %>% 
  mutate(newCol = paste(gameID, rowid(gameID), sep='-'))
#   gameID garboCol newCol
#1     34        1   34-1
#2     34        2   34-2
#3     34        3   34-3
#4     34        4   34-4
#5     34        5   34-5
#6     25        6   25-1
#7     25        7   25-2
#8     25        8   25-3

或与glue(来自glue)一起使用

library(glue)
mydf %>%
     mutate(newCol = glue("{gameID}-{rowid(gameID)}"))

【讨论】:

  • 你认为这可以在没有 group_by'ing 的情况下完成吗?如果不正常,但是 group_by 具有转换为 tibble 的意外后果,这会将许多字符类转换为整数(即​​使它们应该保持字符类型)
  • 实际上最后一条评论是个谎言——我在代码中进一步处理列类类型,所以没关系
  • @Canovic 您可以使用来自data.tablerowid。即mydf %&gt;% mutate(newCol = paste(gameID, rowid(gameID), sep='-'))
【解决方案2】:

这可能是你的想法。

mydf %>% 
 group_by(gameID) %>% 
 dplyr::mutate(newCol = paste0(gameID, '-', seq_along(gameID)))
# A tibble: 8 x 3
# Groups:   gameID [2]
#  gameID garboCol newCol
#  <fct>     <dbl> <chr> 
#1 34            1 34-1  
#2 34            2 34-2  
#3 34            3 34-3  
#4 34            4 34-4  
#5 34            5 34-5  
#6 25            6 25-1  
#7 25            7 25-2  
#8 25            8 25-3 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-15
    • 1970-01-01
    • 2022-07-28
    • 1970-01-01
    • 2017-05-22
    • 2019-08-12
    • 1970-01-01
    相关资源
    最近更新 更多