Есть ли способ сократить каждый элемент объекта в R? - PullRequest
2 голосов
/ 21 ноября 2019

Я хочу сократить каждое слово в объекте длиной более 5 символов и заменить удаленные символы на «.»

, т. Е.

x <- «в этом примерепредложение, которое я дал здесь "</strong>

, станет

" этим экзаменом. сенте. я дал здесь "

Я думаю, что это будетЭто должно быть сделано с помощью цикла, а также может потребоваться разбиение на отдельные строки, но я очень новичок в R и действительно изо всех сил пытаюсь заставить его сделать это. Любая помощь будет принята с благодарностью!

Большое спасибо!

Ответы [ 2 ]

3 голосов
/ 21 ноября 2019

Мой ответ ниже, но попробуйте вместо этого использовать ответ @ user20650. Это намного более кратко и изящно (хотя возможно непостижимо, если вы не знакомы с Регулярными выражениями). Согласно второму комментарию @ user20650, убедитесь, что он достаточно надежен для работы с вашими фактическими данными.

Вот вариант tidyverse:

library(tidyverse)

vec = c("this example sentence I have given here",
      "and here is another long example")

vec.abbrev = vec %>% 
  map_chr(~ str_split(.x, pattern=" ", simplify=TRUE) %>% 
            gsub("(.{5}).*", "\\1.", .) %>% 
            paste(., collapse=" "))
vec.abbrev
[1] "this examp. sente. I have given. here"
[2] "and here is anoth. long examp."

В приведенном выше коде мы используем map_chr для перебора каждого предложения в vec. Канал (%>%) передает результат каждой функции следующей функции.

Символ точки может привести к путанице, поскольку он имеет более одного значения в зависимости от контекста. "(.{5}).*" является Регулярное выражение , в котором . означает «соответствовать любому символу». В "\\1." . на самом деле период. Последний . в gsub("(.{5}).*", "\\1.", .) и первый . в paste(., collapse=" ") - это «местоимение», которое представляет выходные данные предыдущей функции, которую мы передаем в текущую функцию.

Здесьпроцесс пошаговый:

# Split each string into component words and return as a list
vec.abbrev = str_split(vec, pattern=" ", simplify=FALSE)

# For each sentence, remove all letters after the fifth letter in 
#  a word and replace with a period
vec.abbrev = map(vec.abbrev, ~ gsub("(.{5}).*", "\\1.", .x)) 

# For each sentence, paste the component words back together again, 
#  each separated by a space, and return the result as a vector, 
#  rather than a list
vec.abbrev = map_chr(vec.abbrev, ~paste(.x, collapse=" "))
1 голос
/ 21 ноября 2019

Используя for цикл, вы можете сделать:

x <- "this example sentence I have given here"

x2 <- unlist(strsplit(x," "))

x3 <- NULL
for(w in x2)
{
  if(nchar(w) > 5) {
    w <- paste0(substr(w,1,5),".")
  }
  else{}
  x3 <- c(x3,w)
}
x_final <- paste(x3,collapse = " ")

И окончательный вывод:

> x_final
[1] "this examp. sente. I have given here"
...