Цепочное манипулирование строками с несколькими шаблонами и несколькими назначенными заменами [duplicate]

a ~ li {
    background: red
}

В css3 добавлен новый селектор, поэтому, если html выглядит так:

<ul>
  <li>
    <a>Some text</a>
  </li>
</ul>

Фактически вы можете воздействовать на родителя элемента «a», который является «li» «

20
задан zx8754 2 December 2016 в 10:00
поделиться

7 ответов

map = setNames(c("0101", "0102", "0103"), c("AA", "AC", "AG"))
foo[] <- map[unlist(foo)]

, предполагая, что map охватывает все случаи из foo. Это было бы меньше похоже на «взломать» и быть более эффективным как в пространстве, так и во времени, если foo были матрицей (символа ()), затем

matrix(map[foo], nrow=nrow(foo), dimnames=dimnames(foo))

Обе версии матрицы и кадра данных выполняются afoul от ограничения R 2 ^ 31-1 на размер вектора, когда есть миллионы SNP и тысячи образцов.

25
ответ дан Martin Morgan 18 August 2018 в 18:40
поделиться

Если вы открыты для использования пакетов, plyr является очень популярным и имеет эту удобную функцию mapvalues ​​() , которая сделает именно то, что вы ищете:

foo <- mapvalues(foo, from=c("AA", "AC", "AG"), to=c("0101", "0102", "0103"))

Обратите внимание, что он работает для типов данных всех видов, а не только для строк.

21
ответ дан c.gutierrez 18 August 2018 в 18:40
поделиться
  • 1
    К сожалению, это вызывает ошибку в значениях plyr :: mapvalues ​​(foo, from = c ("AA", "AC", "AG"), to = c ("0101", x должен быть атомным вектором. Это также описано в ?mapvalues. – Uwe 30 January 2017 в 10:24

Обратите внимание, что этот ответ начался как попытка решить гораздо более простую проблему, опубликованную в . Как заменить все значения в кадре данных вектором значений? . К сожалению, этот вопрос был закрыт как дубликат актуального вопроса. Итак, я попытаюсь предложить решение, основанное на замене уровней факторов для обоих случаев.


Если существует только вектор (или один столбец фрейма данных), значения которого должны быть заменить и нет возражений против использования фактора, мы можем принудить вектор к коэффициенту и изменить уровни факторов по мере необходимости:

x <- c(1, 1, 4, 4, 5, 5, 1, 1, 2)
x <- factor(x)
x
#[1] 1 1 4 4 5 5 1 1 2
#Levels: 1 2 4 5
replacement_vec <- c("A", "T", "C", "G")
levels(x) <- replacement_vec
x
#[1] A A C C G G A A T
#Levels: A T C G

Используя пакет forcats, это может быть сделано в однострочном режиме:

x <- c(1, 1, 4, 4, 5, 5, 1, 1, 2)
forcats::lvls_revalue(factor(x), replacement_vec)
#[1] A A C C G G A A T
#Levels: A T C G

В случае, если все значения нескольких столбцов кадра данных должны быть заменены, подход может быть расширен.

foo <- data.frame(snp1 = c("AA", "AG", "AA", "AA"), 
                  snp2 = c("AA", "AT", "AG", "AA"), 
                  snp3 = c(NA, "GG", "GG", "GC"), 
                  stringsAsFactors=FALSE)

level_vec <- c("AA", "AC", "AG", "AT", "GC", "GG")
replacement_vec <- c("0101", "0102", "0103", "0104", "0302", "0303")
foo[] <- lapply(foo, function(x) forcats::lvls_revalue(factor(x, levels = level_vec), 
                                                       replacement_vec))
foo
#  snp1 snp2 snp3
#1 0101 0101 <NA>
#2 0103 0104 0303
#3 0101 0103 0303
#4 0101 0101 0302

Обратите внимание, что level_vec и replacement_vec должны иметь равную длину.

Что еще более важно, level_vec должно быть complete , то есть включать все возможные значения в затронутые столбцы исходного фрейма данных. (Для проверки используйте unique(sort(unlist(foo)))). В противном случае любые отсутствующие значения будут принудительно применены к <NA>. Обратите внимание, что это также является требованием для ответа Мартина Морганса .

Итак, если есть только несколько разных значений, которые вы должны заменить, вам, вероятно, будет лучше с одним из других ответы, например, Рамната .

4
ответ дан Community 18 August 2018 в 18:40
поделиться

Вот что-то простое, что выполнит задание:

key <- c('AA','AC','AG')
val <- c('0101','0102','0103')

lapply(1:3,FUN = function(i){foo[foo == key[i]] <<- val[i]})
foo

 snp1 snp2 snp3
1 0101 0101 <NA>
2 0103   AT   GG
3 0101 0103   GG
4 0101 0101   GC

lapply выведет список в этом случае, которого мы действительно не заботимся. Вы можете присвоить результат чему-то, если хотите, а затем просто отбросить его. Я повторяю индексы здесь, но вы можете так же легко поместить ключ / vals в список и перебрать их непосредственно. Обратите внимание на использование глобального присвоения с помощью <<-.

Я применил способ сделать это с помощью mapply, но моя первая попытка не сработала, поэтому я переключился. Я подозреваю, что решение с mapply возможно.

4
ответ дан joran 18 August 2018 в 18:40
поделиться
  • 1
    я бы не советовал использовать глобальный оператор присваивания <<-. – Ramnath 25 September 2011 в 19:59
  • 2
    @Ramnath Согласен, <<- может быть рискованным, но это не по своей сути плохо. – joran 25 September 2011 в 20:02
  • 3
    Это единственный ответ, который может обрабатывать вариант, в котором у оригинала были ключи от 0: 2, и задача заключалась в преобразовании в эквивалентные значения символов. Самый высокий проголосовавший ответ не удался, потому что 0 не является приемлемым показателем. Ответы Рамнатхса и К.гутереса также потерпели неудачу в моих руках. (Я не тестировал все ответы.) Это ссылка на вопрос: stackoverflow.com/questions/49504035/… – 42- 27 March 2018 в 17:20

Так как прошло несколько лет с момента последнего ответа, и сегодня на эту тему появился новый вопрос, и модератор закрыл его, я добавлю его здесь. Плакат имеет большой фрейм данных, содержащий 0, 1 и 2, и хочет изменить их на AA, AB и BB соответственно.

Используйте plyr:

> df <- data.frame(matrix(sample(c(NA, c("0","1","2")), 100, replace = TRUE), 10))
> df
     X1   X2   X3 X4   X5   X6   X7   X8   X9  X10
1     1    2 <NA>  2    1    2    0    2    0    2
2     0    2    1  1    2    1    1    0    0    1
3     1    0    2  2    1    0 <NA>    0    1 <NA>
4     1    2 <NA>  2    2    2    1    1    0    1
... to 10th row

> df[] <- lapply(df, as.character)

Создайте функцию над фреймом данных, используя revalue, чтобы заменить несколько терминов:

> library(plyr)
> apply(df, 2, function(x) {x <- revalue(x, c("0"="AA","1"="AB","2"="BB")); x})
      X1   X2   X3   X4   X5   X6   X7   X8   X9   X10 
 [1,] "AB" "BB" NA   "BB" "AB" "BB" "AA" "BB" "AA" "BB"
 [2,] "AA" "BB" "AB" "AB" "BB" "AB" "AB" "AA" "AA" "AB"
 [3,] "AB" "AA" "BB" "BB" "AB" "AA" NA   "AA" "AB" NA  
 [4,] "AB" "BB" NA   "BB" "BB" "BB" "AB" "AB" "AA" "AB"
... and so on
1
ответ дан mysteRious 18 August 2018 в 18:40
поделиться
  • 1
    Похоже, что ваш ввод - это data.frame, а ваш вывод - это матрица. Я думаю, вы могли бы убедить себя в конце. – Frank 10 May 2018 в 14:28

Вот быстрое решение

dict = list(AA = '0101', AC = '0102', AG = '0103')
foo2 = foo
for (i in 1:3){foo2 <- replace(foo2, foo2 == names(dict[i]), dict[i])}
13
ответ дан Ramnath 18 August 2018 в 18:40
поделиться
  • 1
    может ли кто-нибудь объяснить тихий downvote ??? – Ramnath 26 September 2011 в 03:36
  • 2
    Мне нравится этот ответ, потому что он держит ключи и ценности вместе. Наличие ключей и значений в отдельных символьных векторах означает, что если вы ошиблись в порядке очередности одного из векторов, ваш словарь молча помещает все неправильно упорядоченные записи. – mgriebe 22 May 2014 в 19:32
  • 3
    Единственное различие, которое я хотел бы предложить, - использовать векторизованную нотацию R на третьей строке, например: sapply (1: 3, function (i) replace (foo2, foo2 == names (dict [i]), dict [i])) – c.gutierrez 11 September 2014 в 15:26
  • 4
    Функции *apply не совпадают с векторизованными. – Ramnath 11 September 2014 в 19:27

Используемый ответ @ Ramnath выше, но он прочитал (что заменить и что нужно заменить) из файла и вместо gpub использовать gsub.

hrw <- read.csv("hgWords.txt", header=T, stringsAsFactor=FALSE, encoding="UTF-8", sep="\t") 

for (i in nrow(hrw)) 
{
document <- gsub(hrw$from[i], hrw$to[i], document, ignore.case=TRUE)
}

hgword.txt содержит следующая вкладка разделена

"from"  "to"
"AA"    "0101"
"AC"    "0102"
"AG"    "0103" 
1
ответ дан Vinay Prajapati 18 August 2018 в 18:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: