3
$\begingroup$

I have the following list:

l={"1 atattaggtt tttacctacc caggaaaagc caaccaacct
61 ctctaaacga actttaaaat ctgtgtagct gtcgctcggc
121 gcagtataaa caataataaa"}

which I want to turn into:

{{{1,{"atattaggtt","tttacctacc","caggaaaagc","caaccaacct"}},
    {61,{"ctctaaacga","actttaaaat","ctgtgtagct","gtcgctcggc"}},
    {121,{"gcagtataaa","caataataaa"}}}

I wonder how one does this?

Update: I know that StringReplace[l, WhitespaceCharacter -> ","] gives me:

{"1,atattaggtt,tttacctacc,caggaaaagc,caaccaacct,61,ctctaaacga,\
actttaaaat,ctgtgtagct,gtcgctcggc,121,gcagtataaa,caataataaa"}

Yet I don't know how to sublist this as above.

$\endgroup$
3
  • 3
    $\begingroup$ try StringSplit[lis, ","] $\endgroup$ – Nasser Apr 2 '20 at 19:21
  • 2
    $\begingroup$ @Nasser it was not a simple StringSplit[] $\endgroup$ – Wiliam Apr 2 '20 at 19:50
  • $\begingroup$ I was replying to what you said Yet I don't know how to sublist this as above. not to the main question. $\endgroup$ – Nasser Apr 2 '20 at 19:55
6
$\begingroup$

You may use StringCases with StringExpression.

StringCases[
  n : NumberString ~~ s : (WhitespaceCharacter ~~ LetterCharacter ..) .. :> 
    {FromDigits@n, StringSplit@s}
]@l
{{{1, {"atattaggtt", "tttacctacc", "caggaaaagc", "caaccaacct"}}, 
  {61, {"ctctaaacga", "actttaaaat", "ctgtgtagct", "gtcgctcggc"}}, 
  {121, {"gcagtataaa", "caataataaa"}}}} 

Hope this helps.

$\endgroup$
7
$\begingroup$
{First[#], Rest[#]} & /@ ImportString[#, "Table"] & /@ l

(*    {{{1, {"atattaggtt", "tttacctacc", "caggaaaagc", "caaccaacct"}},
        {61, {"ctctaaacga", "actttaaaat", "ctgtgtagct", "gtcgctcggc"}},
        {121, {"gcagtataaa", "caataataaa"}}}}                              *)
$\endgroup$
5
$\begingroup$

Another way using regular expressions.

StringSplit[l, RegularExpression["(?=[A-Z]|(?<!\\d)\\d)"]] // 
  Map[StringSplit /* ({First@#, Rest@#} &), #, {-1}] &
$\endgroup$
3
$\begingroup$
StringCases[l,
  RegularExpression["([1-9]+)([a-t\s]+)"]:> {"$1", StringSplit["$2"]}
]

{{{1, {atattaggtt, tttacctacc, caggaaaagc, caaccaacct}}, {61, {ctctaaacga, actttaaaat, ctgtgtagct, gtcgctcggc}}, {121, {gcagtataaa, caataataaa}}}}

Original Answer

StringCases[l,RegularExpression["([1-9]+)([a-z\s]+)"]:> {"$1", "$2"}]
  // MapAt[StringSplit, #, {All,All,2}]&
$\endgroup$
3
$\begingroup$
Map[{FromDigits @ #, {##2}} & @@@ # & @* StringSplit] @ StringSplit[l, "\n"]
{{{1, {"atattaggtt", "tttacctacc", "caggaaaagc", "caaccaacct"}}, 
  {61, {"ctctaaacga", "actttaaaat", "ctgtgtagct", "gtcgctcggc"}},
  {121, {"gcagtataaa", "caataataaa"}}}}

Also

f = Normal[{#, DeleteCases[{##2}, ""]} & @@@ SemanticImportString[#]] &;
f /@ l
{{{1, {"atattaggtt", "tttacctacc", "caggaaaagc", "caaccaacct"}}, 
  {61, {"ctctaaacga", "actttaaaat", "ctgtgtagct", "gtcgctcggc"}}, 
  {121, {"gcagtataaa", "caataataaa"}}}}

and

f2 = {FromDigits @ #, {##2}} & @@@ 
      Split[StringSplit @ #, Not @* StringMatchQ[NumberString] @* First] &;
f2 /@ l
 {{{1, {"atattaggtt", "tttacctacc", "caggaaaagc", "caaccaacct"}},
   {61, {"ctctaaacga", "actttaaaat", "ctgtgtagct", "gtcgctcggc"}},
   {121, {"gcagtataaa", "caataataaa"}}}}
$\endgroup$
2
$\begingroup$

So after playing a bit, I found the solution:

x0 = StringSplit[l, Whitespace] // Flatten // ToExpression;
x1 = Split[x0, ! IntegerQ[#2] &];
x2 = Map[Drop[#, 1] &, x1];
x3 = Table[Map[ToString[#] &, x2[[i]]], {i, Length[x2]}];
x4 = Map[Take[#, 1] &, x1] // Flatten;
final = Transpose[{x4, x3}]

To which I get:

{{1, {"atattaggtt", "tttacctacc", "caggaaaagc", 
   "caaccaacct"}}, {61, {"ctctaaacga", "actttaaaat", "ctgtgtagct", 
   "gtcgctcggc"}}, {121, {"gcagtataaa", "caataataaa"}}}

As desired. Maybe you guys can make this more efficient.

$\endgroup$
1
  • 1
    $\begingroup$ Your 'as desired' differs somewhat to that given in your question $\endgroup$ – user1066 Apr 2 '20 at 22:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.