使用tidyr分离多个变量

使用tidyr分离多个变量,r,dataframe,tidyr,R,Dataframe,Tidyr,我有一个数据帧df,有十个变量var1,var2,var3,…,var10要分开。变量的值具有以下形式:值\文本。我想应用tidyr::separate,实际上我做了十次,每个变量一次 tidyr::separate(col=var1,into=c("value1","text1"),extra="merge")%>% tidyr::separate(col=var2,into=c("value2","text2"),extra="merge")%>% 你知道有什么更优雅的方法可

我有一个数据帧df,有十个变量var1,var2,var3,…,var10要分开。变量的值具有以下形式:值\文本。我想应用tidyr::separate,实际上我做了十次,每个变量一次

tidyr::separate(col=var1,into=c("value1","text1"),extra="merge")%>%
tidyr::separate(col=var2,into=c("value2","text2"),extra="merge")%>%


你知道有什么更优雅的方法可以使用tidyr::立即分离而不分离10次吗?

目前我能想到的最好的方法是这样的:

library(tidyverse)
mydf %>% 
  gather(var, val, everything()) %>%            # Gather all the columns into a key-value pair 
  separate(val, into = c("value", "text")) %>%  # Separate the gathered columns
  gather(key, val, value, text) %>%             # Gather again so you have key-key-value
  unite(cn, var, key) %>%                       # Unite your keys to become the column names
  group_by(cn) %>%                              # Keys are duplicated; we need to know their origins
  mutate(rn = sequence(n())) %>%                # .. so we add row numbers
  spread(cn, val)                               # Then we convert to the wide form
# # A tibble: 5 × 21
#      rn var1_text var1_value var10_text var10_value var2_text var2_value var3_text var3_value var4_text var4_value
# * <int>     <chr>      <chr>      <chr>       <chr>     <chr>      <chr>     <chr>      <chr>     <chr>      <chr>
# 1     1      POIL        235       ZHKV         555      QVWK        479      SKCY        454      YCTY        704
# 2     2      NENB        928       CJLE         956      JXQT        379      HPCV        186      VIQY        764
# 3     3      HFHX        966       PZZE         622      PXHE        261      IUGF        717      YIGE        842
# 4     4      LUWK        021       OJRH         741      XNWE        230      NGEN        486      INYN        003
# 5     5      BISI        637       MEJS         718      TSYO        383      ODGS        755      GBKW        564
# # ... with 10 more variables: var5_text <chr>, var5_value <chr>, var6_text <chr>, var6_value <chr>,
# #   var7_text <chr>, var7_value <chr>, var8_text <chr>, var8_value <chr>, var9_text <chr>, var9_value <chr>
# Warning message:
# attributes are not identical across measure variables; they will be dropped 
如果您想坚持使用tidyverse,另一个选项是使用for循环


请附上一份。这使得其他人可以更容易地帮助您。如果您同意不使用tidyr,您可以使用splitstackshape中的cSplit…感谢您的想法,但我更喜欢使用tidyr,然后收集、拆分、再次收集、合并、添加行索引,并将数据分布到各个范围。或者cSplitdf,namesdf,…..更新我对解决方案的想象:我正在考虑类似的东西,但它不起作用错误:无效的列规范:tidyr::separatepaste0Year 2005;,2005:2015,cpaste0Value 200;,‌​2005:2015,0吨‌​分机,2005:2015,ex‌​tra=合并,转换=‌​谢谢你的回复。我非常感谢你在这个详细的答复中所作的努力。然而,我正在寻找更简单的方法。变量名称的形式如下:2005年,2006年…2010年。新的分离变量应具有以下形式:Value_2005、Text_2005、Value_2006、Text_2006…Value_2010、Text_2010。因此,我考虑过这样的问题,但它不起作用。错误:无效的列规范:tidyr::separatepaste0Year\u2005:2015,cpaste0Value\u2005:2015,paste0Text\u2005:2015,extra=merge,convert=TRUE@ungatoverde我希望你在我的帖子里看到我的笔记。您所做的与整洁数据原则背道而驰,因此使用tidyverse不太可能找到一个方便的解决方案。@ungatovide,另一个选项可能是使用for循环,在该循环中,您在名称之间循环,并将它们单独分开。。。。不应该太难处理。@ungatovide,例如:因为我的名字是mydf,mydf很棒!我喜欢这个建议。如果你把它作为我问题的答案,我会接受的。谢谢
library(stringi)
set.seed(1)
mydf <- data.frame(matrix(sprintf("%s_%s", stri_rand_strings(50, 3, "[0-9]"), 
                                  stri_rand_strings(50, 4, "[A-Z]")), ncol = 10,
                          dimnames = list(NULL, paste0("var", 1:10))))
mydf
#       var1     var2     var3     var4     var5     var6     var7     var8     var9    var10
# 1 235_POIL 479_QVWK 454_SKCY 704_YCTY 924_JDJQ 883_TYMP 206_BCJE 214_FDZI 944_DFVS 555_ZHKV
# 2 928_NENB 379_JXQT 186_HPCV 764_VIQY 362_KRRO 794_MCGM 877_HEGE 959_NRCD 174_GMCJ 956_CJLE
# 3 966_HFHX 261_PXHE 717_IUGF 842_YIGE 470_LLHP 733_JYNI 448_MUAN 734_BYRC 522_ZQRI 622_PZZE
# 4 021_LUWK 230_XNWE 486_NGEN 003_INYN 838_XDKF 727_HUSE 663_WJBD 107_MMJZ 550_KZWY 741_OJRH
# 5 637_BISI 383_TSYO 755_ODGS 564_GBKW 334_LDLY 121_BTQE 296_IEDF 146_EVBK 069_VUGT 718_MEJS
library(splitstackshape)
cSplit(mydf, names(mydf), "_", type.convert = FALSE)
##    var1_1 var1_2 var2_1 var2_2 var3_1 var3_2 var4_1 var4_2 var5_1 var5_2 var6_1 var6_2 var7_1 var7_2 var8_1 var8_2
## 1:    235   POIL    479   QVWK    454   SKCY    704   YCTY    924   JDJQ    883   TYMP    206   BCJE    214   FDZI
## 2:    928   NENB    379   JXQT    186   HPCV    764   VIQY    362   KRRO    794   MCGM    877   HEGE    959   NRCD
## 3:    966   HFHX    261   PXHE    717   IUGF    842   YIGE    470   LLHP    733   JYNI    448   MUAN    734   BYRC
## 4:    021   LUWK    230   XNWE    486   NGEN    003   INYN    838   XDKF    727   HUSE    663   WJBD    107   MMJZ
## 5:    637   BISI    383   TSYO    755   ODGS    564   GBKW    334   LDLY    121   BTQE    296   IEDF    146   EVBK
##    var9_1 var9_2 var10_1 var10_2
## 1:    944   DFVS     555    ZHKV
## 2:    174   GMCJ     956    CJLE
## 3:    522   ZQRI     622    PZZE
## 4:    550   KZWY     741    OJRH
## 5:    069   VUGT     718    MEJS
for (i in names(mydf)) mydf <- separate_(mydf, i, paste0(i, c("_text", "_value")))