2

I would like to show subsequent prints of the data more consistently in R data.table. In Vim, you can do it with tapstop and csv.vim, for instance. Code

library(data.table)

# http://stackoverflow.com/a/43706344/54964

DF[time < 8]

# print other data
DF[time < 10]

Output where the location of the second column varies because of varying length of items in the second column from (7.7 to 10.8)

                      Z A_t AtPE
1:                    A 7.7 1.28
2:                    B 9.6 1.60
[1] other data
1:                    C  9.0 1.50
2:                    A 10.8 1.80

Expected output

                      Z  A_t AtPE
1:                    A  7.7 1.28
2:                    B  9.6 1.60
[1] other data
1:                    C  9.0 1.50
2:                    A 10.8 1.80

Example of my commands

field <- "Acute"
sprintf("%s ", field)
# http://stackoverflow.com/a/43714690/54964
cat(capture.output(unname(DF[order(time)][time < 15 & Field == field, .(Field)])[])[-1], sep="\n")

field <- "An"
sprintf("%s ", field)
cat(capture.output(unname(DF[order(time)][time < 15 & Field == field, .(Field)])[])[-1], sep="\n")

field <- "En"
sprintf("%s ", field)
cat(capture.output(unname(DF[order(time)][time < 15 & Field == field, .(Field)])[])[-1], sep="\n")
Léo Léopold Hertz 준영
  • 134,464
  • 179
  • 445
  • 697
  • You meant to use the variable defined inside the `data.table`, instead of the `cat`? – akrun May 01 '17 at 13:47
  • The value's you mentione are not i nyour example. If i use `field <- "Acute"; DF[order(time)][time < 15 & Field == field, .(Field)]# Field 1: Acute 2: Acute 3: Acute 4: Acute 5: Acute 6: Acute` – akrun May 01 '17 at 13:49
  • 1
    I guess I understand what you meant. Instead of subsetting each separately, why not put it in a loop and do it i.e. `lapply(c("Acute", "An", "En"), function(x) DF[order(time)[time < 15 & Field == x, .(Field)])` the other parts would be the same as my update – akrun May 01 '17 at 13:55
  • 1
    Could you please check my update. The first name is a bit long, so the format width needs to be adjusted for it – akrun May 01 '17 at 14:04
  • 1
    Also, I guess `v1 <- format(trimws(v1), width = max(nchar(v1)+max(nchar(nm1))), justify = "left")` the justify = left seems to be better here – akrun May 01 '17 at 14:10
  • 1

1 Answers1

2

We could do this by placing it in a list and then do the capture.output with some tweaking

v1 <- capture.output(lapply(list(DF[time < 8], DF[time < 10]), unname))
v2 <- v1[!grepl("\\[", v1)]
i1 <- v2=="" &  seq_along(v2) != length(v2)
v2[i1] <- sprintf("[%d] other data", seq_along(i1[i1]))

and now we print it

cat(v2[trimws(v2)!=""], sep="\n")
# 1: Acute 0.0  0 A 6 0.000000
# 2:    An 7.7 26 B 6 1.283333
# 3:    Fo 0.0  0 B 5 0.000000
# 4: Acute 7.5  1 C 6 1.250000
# 5:    An 7.9 43 C 6 1.316667
# 6:    En 0.0  0 C 6 0.000000
# 7:    Fo 5.4  1 C 5 1.080000
# 8:    An 7.8 77 D 6 1.300000
# 9:    En 0.0  0 D 6 0.000000
#10:    Fo 0.0  0 D 5 0.000000
#11: Acute 0.0  0 E 6 0.000000
#12:    An 7.9 60 E 6 1.316667
#13:    Fo 0.0  0 E 5 0.000000
#14:    Fo 7.9  3 F 5 1.580000
#[1] other data
# 1: Acute 0.0   0 A 6 0.000000
# 2:    An 9.0 120 A 6 1.500000
# 3:    Fo 9.2   2 A 5 1.840000
# 4: Acute 8.3   1 B 6 1.383333
# 5:    An 7.7  26 B 6 1.283333
# 6:    Fo 0.0   0 B 5 0.000000
# 7: Acute 7.5   1 C 6 1.250000
# 8:    An 7.9  43 C 6 1.316667
# 9:    En 0.0   0 C 6 0.000000
#10:    Fo 5.4   1 C 5 1.080000
#11: Acute 8.6   2 D 6 1.433333
#12:    An 7.8  77 D 6 1.300000
#13:    En 0.0   0 D 6 0.000000
#14:    Fo 0.0   0 D 5 0.000000
#15: Acute 0.0   0 E 6 0.000000
#16:    An 7.9  60 E 6 1.316667
#17:    Fo 0.0   0 E 5 0.000000
#18: Acute 8.3   4 F 6 1.383333
#19:    An 8.2 326 F 6 1.366667
#20:    Fo 7.9   3 F 5 1.580000

Update

We need to explicitly call the justify in format to align it

v1 <- do.call(c, lapply(list(DF[time < 8], DF[time < 10]),
     function(x) capture.output(unname(x))))
v1 <- format(trimws(v1), width = max(nchar(v1)), justify = "right")
i1 <- trimws(v1)=="" & seq_along(v1) != 1
v1[i1] <- format(sprintf("[%d] other data", seq_along(i1[i1])),
           width = max(nchar(v1)), justify = "left")

Now, we call the cat

cat(v1[-1], sep="\n")
#  1: Acute 0.0  0 A 6 0.000000
#  2:    An 7.7 26 B 6 1.283333
#  3:    Fo 0.0  0 B 5 0.000000
#  4: Acute 7.5  1 C 6 1.250000
#  5:    An 7.9 43 C 6 1.316667
#  6:    En 0.0  0 C 6 0.000000
#  7:    Fo 5.4  1 C 5 1.080000
#  8:    An 7.8 77 D 6 1.300000
#  9:    En 0.0  0 D 6 0.000000
# 10:    Fo 0.0  0 D 5 0.000000
# 11: Acute 0.0  0 E 6 0.000000
# 12:    An 7.9 60 E 6 1.316667
# 13:    Fo 0.0  0 E 5 0.000000
# 14:    Fo 7.9  3 F 5 1.580000
#[1] other data                
# 1: Acute 0.0   0 A 6 0.000000
# 2:    An 9.0 120 A 6 1.500000
# 3:    Fo 9.2   2 A 5 1.840000
# 4: Acute 8.3   1 B 6 1.383333
# 5:    An 7.7  26 B 6 1.283333
# 6:    Fo 0.0   0 B 5 0.000000
# 7: Acute 7.5   1 C 6 1.250000
# 8:    An 7.9  43 C 6 1.316667
# 9:    En 0.0   0 C 6 0.000000
#10:    Fo 5.4   1 C 5 1.080000
#11: Acute 8.6   2 D 6 1.433333
#12:    An 7.8  77 D 6 1.300000
#13:    En 0.0   0 D 6 0.000000
#14:    Fo 0.0   0 D 5 0.000000
#15: Acute 0.0   0 E 6 0.000000
#16:    An 7.9  60 E 6 1.316667
#17:    Fo 0.0   0 E 5 0.000000
#18: Acute 8.3   4 F 6 1.383333
#19:    An 8.2 326 F 6 1.366667
#20:    Fo 7.9   3 F 5 1.580000

Update2

Based on the OP's comments

nm1 <- c("Acute", "An", "En")
v1 <- do.call(c, lapply(nm1, function(x) 
    capture.output(unname(DF[order(time)][time < 15 & Field == x, .(Field)]))))
v1 <- format(trimws(v1), width = max(nchar(v1)+max(nchar(nm1))), justify = "right")
i1 <- trimws(v1)=="" 
v1[i1] <- format(sprintf("[%d] %s", seq_along(i1[i1]), nm1),
          width = max(nchar(v1)), justify = "left")
cat(v1, sep="\n") 
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    @LéoLéopoldHertz준영 I think it has to do the insertion of 'other data' there. I tried `v1 <- do.call(c, lapply(list(DF[time < 8], DF[time < 10]), function(x) capture.output(unname(x))));i1 <- trimws(v1)=="" & seq_along(v1) != 1;v1[i1] <- sprintf("[%d] other data", seq_along(i1[i1])); cat(v1, sep="\n")` – akrun May 01 '17 at 07:24
  • @LéoLéopoldHertz준영 I did some more manipulation to keep the same character length., but something with `cat` is still making it pushed `v1 <- do.call(c, lapply(list(DF[time < 8], DF[time < 10]), function(x) capture.output(unname(x)))); v1 <- format(v1, width = max(nchar(v1))); i1 <- trimws(v1)=="" & seq_along(v1) != 1; v1[i1] <- format(sprintf("[%d] other data", seq_along(i1[i1])), width = max(nchar(v1)));cat(v1, sep="\n")` have to look into the `cat` function – akrun May 01 '17 at 07:29
  • 1
    Now the nchar is same `nchar(v1)# [1] 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30` I have to go now. Will check later – akrun May 01 '17 at 07:30
  • 1
    @LéoLéopoldHertz준영 Please check the updated post. I think it is the `justify` that created the trouble – akrun May 01 '17 at 13:12
  • @LéoLéopoldHertz준영 I am not sure I understand your query – akrun May 01 '17 at 13:32
  • @LéoLéopoldHertz준영 Okay, I thought your values will be `Other1`, `Other2` etc. In that case, keep it as a vector and paste i.e. `v2 <- c("A", "B"); format(sprintf("[%d] %s", seq_along(i1[i1]), v2), ...` – akrun May 01 '17 at 13:37
  • 1
    Beautiful output! I confirm that Update 2 works and gives aesthetically satisfying output. – Léo Léopold Hertz 준영 May 01 '17 at 14:10