Replace loop for apply or sappy?

问题内容:

I have a program, but I need to replace loop for apply or sapply? Is this possible in my case? Can you help me?

My code

TD = stri_read_lines("script.R")

chars = data.frame()
for(i in 1:length(TD)){
  if(TD[i] !='') {  
    char= unlist(strsplit(TD[i], split=""))
        for ( j in 1:nchar(TD[i]) ) {     
      chars =rbind(chars , data.frame(a=char[j], b=i, c= j))
   }
  }  
}

> dput(head(TD))
"data.frame()"

Result

   a b  c
1  d 1  1
2  a 1  2
3  t 1  3
4  a 1  4
5  . 1  5
6  f 1  6
7  r 1  7
8  a 1  8
9  m 1  9
10 e 1 10
11 ( 1 11
12 ) 1 12

问题评论:

1  
What is TD?… Also please post a reproducible example along with expected output.
1  
@Kim Please use dput(head(TD)) to show your data!

答案:

答案1:

strsplit is already vectorized, so it’s better to use it that way than in a loop. I’ll be reading in one of my own scripts, since I don’t have yours.

library(stringi)

TD <- stri_read_lines("~/R/My Scripts/capitalize.R")
cat(TD[1:3], sep = "\n")
# capitalize_first <- function(x) {
#   # Capitalize the first word in each value of a character vector.
#   result <- as.character(x)

First we’ll remove the blank lines.

TD <- TD[TD != ""]

Then we’ll create a list, where each element is a vector of the characters in a line. We’ll also get the length of each (i.e., number of characters in a line).

line_characters <- strsplit(TD, "")
line_lengths <- lengths(line_characters)

The one column you want is all the characters in a single vector. unlist does this.

all_characters <- unlist(line_characters)

Another column is the line number each character comes from. Using rep, we can repeat each number in the sequence 1, 2, … once for each character in the line.

line_identifier <- rep(
  seq_along(line_characters),
  line_lengths
)

The third column is the index of the character in the line. Using line_lengths again, we can create a list of sequences, each from 1 to the length of its line. Then unlist collapses them into a single vector.

index_in_line <- unlist(
  lapply(line_lengths, seq_len)
)

Now to just combine them in a data.frame. I’ve also shown a part where the data crosses lines.

chars <- data.frame(
  a = all_characters,
  b = line_identifier,
  c = index_in_line
)

chars[21:40, ]
#    a b  c
# 21 f 1 21
# 22 u 1 22
# 23 n 1 23
# 24 c 1 24
# 25 t 1 25
# 26 i 1 26
# 27 o 1 27
# 28 n 1 28
# 29 ( 1 29
# 30 x 1 30
# 31 ) 1 31
# 32   1 32
# 33 { 1 33
# 34   2  1
# 35   2  2
# 36 # 2  3
# 37   2  4
# 38 C 2  5
# 39 a 2  6
# 40 p 2  7

答案评论:

    
And how can I find, for example c(“a,” b “,” c”)?
– Kim
36 mins ago

答案2:

Here is a compact solution with base R:

TD <- c("data.frame()", "", "one more line")
L <- strsplit(TD, split="")
data.frame(a=unlist(L), b=rep(1:length(TD), nchar(TD)), c=sequence(nchar(TD)))

答案评论:

    
How can I ensure that the program also finds character types like \ t, \ n?
– Kim
1 hour ago
    
And how can I find, for example c(“a,” b “,” c”)?
– Kim
36 mins ago

答案3:

Short answer using lapply.

data.frame(a = unlist(strsplit(TD, split = "")),
           b = rep(seq_along(TD), nchar(TD)),
           c = unlist(lapply(nchar(TD), seq_len)))

答案评论:

    
@Kim, It does find also those characters.
    
And how can I find, for example c(“a,” b “,” c”)?
– Kim
36 mins ago

原文地址:

https://stackoverflow.com/questions/47755314/replace-loop-for-apply-or-sappy

添加评论

友情链接:蝴蝶教程