Добавлять индекс только если элемент появляется более одного раза в R - PullRequest
2 голосов
/ 27 февраля 2020

Ввод:

x <- list("&a", NULL, "&b", "&a", "", "&c", "&c", "&a", list())

Желаемый вывод:

Добавить индекс, если элемент появляется более одного раза, и если элемент не длина 0, NULL или пустая строка

list("&a(1)", NULL, "&b", "&a(2)", "", "&c(1)", "&c(2)", "&a(3)", list())

То, что я пробовал:

Это работает, но, конечно, не выглядит элегантно / эффективно.

x <- list("&a", NULL, "&b", "&a", "", "&c", "&c", "&a", list())
tbl <- table(unlist(x))

for(name in names(tbl)){
  idx <- which(name == x)
  if(nchar(name) & length(idx)) x[idx] <- glue("{name}({1:length(idx)})")
}
x

Если вопрос лучше подходит для проверки кода, я, конечно, перенесу его.

Ответы [ 3 ]

2 голосов
/ 27 февраля 2020

Вы можете использовать duplicated, чтобы найти дубликаты, и использовать paste0 и seq_along, чтобы добавить к ним индекс:

for(name in unique(x[duplicated(x) & x!=""])) {
    i <- which(name == x)
    x[i] <- paste0(x[i],"(",seq_along(i),")")
}
x
#[[1]]
#[1] "&a(1)"
#
#[[2]]
#NULL
#
#[[3]]
#[1] "&b"
#
#[[4]]
#[1] "&a(2)"
#
#[[5]]
#[1] ""
#
#[[6]]
#[1] "&c(1)"
#
#[[7]]
#[1] "&c(2)"
#
#[[8]]
#[1] "&a(3)"
#
#[[9]]
#list()
1 голос
/ 27 февраля 2020

Вот один базовый подход R:

#Replace NA with NULL
x[sapply(x, is.null)] <- NA
#Convert x to vector
x1 <- unlist(x)
#Get indices where the length of x1 is more than 1
inds <- which(as.integer(ave(x1, x1, FUN = length)) > 1)
#Paste those indices with index
x[inds] <- ave(x1[inds], x1[inds], FUN = function(y)
                paste0(y, '(', seq_along(y), ')'))

x
#[[1]]
#[1] "&a(1)"

#[[2]]
#[1] NA

#[[3]]
#[1] "&b"

#[[4]]
#[1] "&a(2)"

#[[5]]
#[1] ""

#[[6]]
#[1] "&c(1)"

#[[7]]
#[1] "&c(2)"

#[[8]]
#[1] "&a(3)"

#[[9]]
#list()
0 голосов
/ 27 февраля 2020

Другое решение с основанием R, но с for-l oop

x <- list("&a", NULL, "&b", "&a", "", "&c", "&c", "&a", list())
# make a vector of index for each element of the list
u <- c(rep(1,length(unlist(unique(x))))) ; names(u) <- unlist(unique(x))

for(i in 1:length(x)){
  # if element is not null and it's in names of the index vector
  if(!is.null(x[[i]]) && x[[i]] %in% names(u)){
    # stock temporary the value
    tmp <- x[[i]]
    # add the index to the value
    x[[i]] <- paste(tmp,'(',u[names(u)==tmp],')',sep = '')
    # increment the index
    u[names(u)==tmp] <- u[names(u)==tmp] + 1
  }
}
x
# [[1]]
# [1] "&a(1)"
# 
# [[2]]
# NULL
# 
# [[3]]
# [1] "&b(1)"
# 
# [[4]]
# [1] "&a(2)"
# 
# [[5]]
# [1] "(1)"
# 
# [[6]]
# [1] "&c(1)"
# 
# [[7]]
# [1] "&c(2)"
# 
# [[8]]
# [1] "&a(3)"
# 
# [[9]]
# list()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...