我有一个包含两列的数据框,最后一列有重复:
#reproducible data my.df <- data.frame(nr = paste(1:6,1,sep="_"), text = c("aa","bb","aa",NA,"bb","xxxx")) nr text 1 1_1 aa 2 2_1 bb 3 3_1 aa 4 4_15 5_1 bb 6 6_1 xxxx
我想在第一列中对值进行分组,然后添加第二列的值.我找到了一种方法来做到这一点:
apply(aggregate(nr~text, my.df, FUN=function(x) paste0(x, collapse = "/"))[,c(2,1)],1,FUN=function(x) paste(x[1],x[2], sep = ": "))
这使:
"1_1/3_1: aa" "2_1/5_1: bb" "6_1: xxxx"
这是我想要的结果,但代码似乎相当长.我觉得必须有一个更好的,也许更快的方法来做到这一点?
哦,是的,NA应该从结果中删除.
编辑:感谢所有的答案.我认为有一个比我自己更容易的解决方案,但显然没有.可读性是(恕我直言)非常主观,所以我做了一个基准:
microbenchmark(RHA(my.df),Heroka_DT(my.df),Heroka_Base(my.df),Jubbles(my.df),times=100L) Unit: milliseconds expr min lq mean median uq RHA(my.df) 9.116587 9.315988 9.662611 9.572361 10.036792 Heroka_DT(my.df) 12.148374 12.448035 13.009290 12.766685 13.475480 Heroka_Base(my.df) 2.947448 6.910890 7.475239 7.172847 7.614657 Jubbles(my.df) 16.615067 40.609642 42.265267 41.799625 43.056632 max neval 10.78943 100 21.12477 100 15.97665 100 61.68414 100
在这种情况下,基本解决方案显然比其他解决方 由于Heroka有最短和最快的解决方案,我会接受他的回答.
你可以使用data.table,它有点短,(恕我直言)更具可读性:
library(data.table) res <- setDT(my.df)[!is.na(text),.(output=sprintf("%s: %s",paste(nr,collapse="/"),text)),text][,output] res > res [1] "1_1/3_1: aa" "2_1/5_1: bb" "6_1: xxxx"
我们可以在base-R中做一些非常相似的事情:
sapply(split(my.df, my.df$text),function(x){with(x, sprintf("%s: %s",paste(nr, collapse="/"),text[1]))}) aa bb xxxx "1_1/3_1: aa" "2_1/5_1: bb" "6_1: xxxx"