这个问题是从here开始讨论的.我觉得,进一步的阐述补充保证了发布一个新问题,因为它与原始帖子中的问题不同.如果我错了,请道歉.

给定与以下类似的数据帧:

mydf <- data.frame(X1=c("0_times","3-10_times", "11-20_times", "1-2_times","3-10_times",
                        "0_times","3-10_times", "11-20_times", "1-2_times","3-10_times" ),
                   X2=c('ab','bb','cb','db','eb','ab','bb','cb','db','eb'),
                   X3=c("11-20_times", "3-10_times","1-2_times","21-30_times","more_than_30_times",
                        "11-20_times", "3-10_times","1-2_times","21-30_times","more_than_30_times"),
                   X4=c("foo", "bar","fizz","buzz","weee","foo", "bar","fizz","buzz","weee"),
                   X5=c("3-10_times","1-2_times","0_times","more_than_30_times","11-20_times",
                        "21-30_times","1-2_times","0_times","3-10_times","11-20_times")
                   )

我想创建第二个数据帧来存储列名和来自第一个数据帧的唯一值的列表/向量.

结果如下:

 names   vals
1    X1 0_times, 1-2_times, 3-10_times, 11-20_times
2    X2 ab, bb, cb, db, eb
3    X3 1-2_times, 3-10_times, 11-20_times , 21-30_times, more_than_30_times 
4    X4 foo, bar, fizz, buzz, weee 
1    X5 0_times,1-2_times,3-10_times,11-20_times,21-30_times

我使用以下方法创建第二个数据帧:

mydf2 <- data.frame(names = colnames(mydf))
mydf2$vals <- lapply(mydf, unique)

我认为到目前为止还可以.然而,我面临的挑战是,我需要包含数字的向量(在本例中只有mydf2$X1个)以升序排序,而不仅仅是使用每个项目的第一个数字.

在a Stack user的大力帮助下,这是一种对包含数字的向量进行排序的方法,它在单个向量上运行良好:

mylist <- c('0_times','3-10_times','11_20_times','1-2_times','more_than_20_times')

o <- sapply(strsplit(mylist, '\\D+'), function(x) min(as.numeric(x[nzchar(x)])))
mylist[order(o)]

当我试图通过替换列名将其应用于整个mydf2$vals列时:

o <- sapply(strsplit(mydf2$vals, '\\D+'), function(x) min(as.numeric(x[nzchar(x)])))
mydf2$vals[order(o)]

我收到错误error in evaluating the argument 'X' in selecting a method for function 'sapply': non-character argument

我有两个问题:

  1. 有没有更简单的方法来实现我的目标?
  2. 如何修改建议的排序函数以避免出现错误?

推荐答案

可以将@Allan Cameron's logic封装在一个函数中,将其扩展为对列的unique个值进行排序.if包括数字,grepl将告诉我们,我们应用逻辑.我将其命名为makeLevels,因为创建因子水平可能也很有用.

makeLevels <- \(x) {
  if (any(grepl('\\d', x))) {
    unique(x[order(sapply(strsplit(x, '\\D+'), function(x) min(as.numeric(x[nzchar(x)]))))])
  } else {
    sort(unique(x))
  }
}

lapply(names(mydf), \(x) data.frame(names=x, vals=toString(makeLevels(mydf[[x]])))) |>
  do.call(what=rbind)
#   names                                                                         vals
# 1    X1                                  0_times, 1-2_times, 3-10_times, 11-20_times
# 2    X2                                                           ab, bb, cb, db, eb
# 3    X3          1-2_times, 3-10_times, 11-20_times, 21-30_times, more_than_30_times
# 4    X4                                                   bar, buzz, fizz, foo, weee
# 5    X5 0_times, 1-2_times, 3-10_times, 11-20_times, 21-30_times, more_than_30_times

Or做这样的事,

lapply(names(mydf), \(x) sprintf('$ %s <%s>: %s', x, class(mydf[[x]]), toString(makeLevels(mydf[[x]])))) |>
  do.call(what=rbind)
#      [,1]                                                                                            
# [1,] "$ X1 <character>: 0_times, 1-2_times, 3-10_times, 11-20_times"                                 
# [2,] "$ X2 <character>: ab, bb, cb, db, eb"                                                          
# [3,] "$ X3 <character>: 1-2_times, 3-10_times, 11-20_times, 21-30_times, more_than_30_times"         
# [4,] "$ X4 <character>: bar, buzz, fizz, foo, weee"                                                  
# [5,] "$ X5 <character>: 0_times, 1-2_times, 3-10_times, 11-20_times, 21-30_times, more_than_30_times"

这与str(mydf)的作用相似;如果你想读的话,你实际上可以读lapplymakeLevelsstr.

str(lapply(mydf, makeLevels), vec.len=10L)
# List of 5
#  $ X1: chr [1:4] "0_times" "1-2_times" "3-10_times" "11-20_times"
#  $ X2: chr [1:5] "ab" "bb" "cb" "db" "eb"
#  $ X3: chr [1:5] "1-2_times" "3-10_times" "11-20_times" "21-30_times" "more_than_30_times"
#  $ X4: chr [1:5] "bar" "buzz" "fizz" "foo" "weee"
#  $ X5: chr [1:6] "0_times" "1-2_times" "3-10_times" "11-20_times" "21-30_times" "more_than_30_times"

...

R相关问答推荐

获取一个数据库框架的摘要,该数据库框架将包含一列数据库框架,

derrr summarise每个组返回多行?

bslib::card_header中的shine::downloadButton,图标而不是文本

如何编辑gMarginal背景以匹配绘图背景?

移除仪表板Quarto中顶盖和车身之间的白色区域

即使硬币没有被抛出,也要保持对其的跟踪

找出二叉树中每个 node 在R中的深度?

Ggplot2中geom_tile的动态zoom

R-按最接近午夜的时间进行筛选

正则表达式在第二个管道和第二个T之后拆分R中的列

将摘要图添加到facet_WRAP gglot的末尾

如何判断代码是否在R Markdown(RMD)上下文中交互运行?

如何从嵌套数据中自动创建命名对象?在R中

R将函数参数传递给ggploy

如何获取R chromote中的当前URL?

每行不同列上的行求和

条形图中的条形图没有try 赋予它们的 colored颜色

识别部分重复行,其中一行为NA,其重复行为非NA

我有2011-2022年的年度数据.如何计算最低年份和最高年份之间的差额?

如何根据顺序/序列从数据框中排除值