按行排序然后连接数据框的特定列
Row-wise sort then concatenate across specific columns of data frame
(相关question不包含排序,不需要排序的时候用paste
很简单。)
我有一个结构不太理想的 table,字符列是通用的 "item1"、"item2" 等。我想创建一个新的字符变量,它是这些列的字母顺序、逗号分隔的串联。因此,例如,在第 5 行中,如果 item1 = "milk"、item2 = "eggs" 和 item3 = "butter",第 5 行中的新变量可能是 "butter, eggs, milk"
我在下面编写了一个函数 f()
,它适用于两个字符变量。但是,我遇到了麻烦
- 使用
mapply
或其他"vectorization"(我知道这真的只是一个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
我的第一个想法是这样做:
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)]
只需申请下行:
apply(df,1,function(x){
paste(sort(x),collapse = ",")
})
如果需要,可以将其包装在一个函数中。您要么必须定义要发送的列,要么承担全部。即应用(df[ ,2:3],1,f()...
sort(x) 与 x[order(x)]
相同
(相关question不包含排序,不需要排序的时候用paste
很简单。)
我有一个结构不太理想的 table,字符列是通用的 "item1"、"item2" 等。我想创建一个新的字符变量,它是这些列的字母顺序、逗号分隔的串联。因此,例如,在第 5 行中,如果 item1 = "milk"、item2 = "eggs" 和 item3 = "butter",第 5 行中的新变量可能是 "butter, eggs, milk"
我在下面编写了一个函数 f()
,它适用于两个字符变量。但是,我遇到了麻烦
- 使用
mapply
或其他"vectorization"(我知道这真的只是一个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
我的第一个想法是这样做:
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)]
只需申请下行:
apply(df,1,function(x){
paste(sort(x),collapse = ",")
})
如果需要,可以将其包装在一个函数中。您要么必须定义要发送的列,要么承担全部。即应用(df[ ,2:3],1,f()...
sort(x) 与 x[order(x)]
相同