【问题标题】:Row-wise sort then concatenate across specific columns of data frame逐行排序然后跨数据框的特定列连接
【发布时间】:2015-04-28 02:32:36
【问题描述】:

(相关question不包括排序。当你不需要排序时,很容易使用paste。)

我有一个结构不太理想的表,其中的字符列是通用的“item1”、“item2”等。我想创建一个新的字符变量,它是这些列的字母顺序、逗号分隔的串联.例如,在第 5 行中,如果 item1 = "milk"、item2 = "eggs" 和 item3 = "butter",则第 5 行中的新变量可能是“butter,eggs,milk”

我在下面写了一个函数f(),它适用于两个字符变量。但是,我遇到了麻烦

  • 使用mapply 或其他“矢量化”(我知道这实际上只是一个 for 循环)
  • 将函数推广到任意数量的列

非常感谢任何帮助。

df <- data.frame(a =c("foo","bar"), 
                 b= c("baz","qux"))   
paste(df$a,df$b, sep=", ")
# returns [1] "foo, baz" "bar, qux" ... but I want [1] "baz, foo" "bar, qux"

f <- function(a,b) paste(c(a,b)[order(c(a,b))],collapse=", ")
f("foo","baz") 
# returns [1] "baz, foo" ... which is what I want ... how to vectorize?

df$new_var <- mapply(f, df$a, df$b)
df 
#     a   b new_var      <- new_var is not what I want
# 1 foo baz    1, 2
# 2 bar qux    1, 2

# Interestingly, data.table is smart enough to fix my bad mapply
library(data.table)
dt <- data.table(a =c("foo","bar"), 
                 b= c("baz","qux"))  
dt[,new_var:=mapply(f, a, b)]
dt
#     a    b  new_var    <- new var IS what I want
# 1: foo baz baz, foo
# 2: bar qux bar, qux

【问题讨论】:

    标签: r sorting row string-concatenation mapply


    【解决方案1】:

    只需向下应用行:

    apply(df,1,function(x){
      paste(sort(x),collapse = ",")
    })
    

    如果需要,可以将其包装在一个函数中。您要么必须定义要发送的列,要么假定所有列。即应用(df[,2:3],1,f()...

    sort(x) 与 x[order(x)] 相同

    【讨论】:

      【解决方案2】:

      我的第一个想法是这样做:

      dt[, new_var := paste(sort(.SD), collapse = ", "), by = 1:nrow(dt)]
      

      但是你可以通过几个简单的修改来让你的函数工作:

      f = function(...) paste(c(...)[order(c(...))],collapse=", ")
      
      dt[, new_var := do.call(function(...) mapply(f, ...), .SD)]
      

      【讨论】:

        猜你喜欢
        • 2011-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        • 1970-01-01
        • 2020-05-24
        相关资源
        最近更新 更多