Создание значения в одном столбце на основе совпадения строк в любом из нескольких столбцов

У меня есть фрейм данных, который содержит возможные значения «c1», «c2», «c3» или «нет» для нескольких строк и нескольких столбцов. Любая заданная строка содержит либо «нет», либо только один других значений... то есть ни одна строка не содержит как c1, так и c2.

Что я хочу сделать, так это создать новый столбец, который содержит значение, отличное от «нет», для каждой строки, если Любые столбцов содержит значение, отличное от «нет»; в противном случае остается «нет». Думаю, это должно быть просто, но я не понимаю.

Вот пример данных... сохраните как "test1.csv"

Group1,Group2,Group3,Group4,Group5,Group6
c1,no,no,c1,no,no
no,no,c1,no,no,no
no,no,no,no,c1,no
no,no,no,no,no,no
c1,no,no,no,no,c1
no,c1,no,no,no,no
c2,no,no,no,no,no
no,c2,no,c2,no,no
no,no,no,no,no,no
no,no,no,no,no,c2
c3,no,c3,no,c3,no
no,no,no,no,no,no
no,no,c3,c3,no,no

Вот что я пытался сделать:

df <- read.csv("test1.csv")
df$any <- "no"
df$any[df == "c1"] <- "c1"
df$any[df == "c2"] <- "c2"
df$any[df == "c3"] <- "c3"

Что возвращает следующую ошибку:

Error in `$<-.data.frame`(`*tmp*`, any, value = c("c1", "no", "no", "no",  : 
  replacement has 91 rows, data has 13

Успешный вывод должен выглядеть так:

   Group1 Group2 Group3 Group4 Group5 Group6 any
1      c1     no     no     c1     no     no  c1
2      no     no     c1     no     no     no  c1
3      no     no     no     no     c1     no  c1
4      no     no     no     no     no     no  no
5      c1     no     no     no     no     c1  c1
6      no     c1     no     no     no     no  c1
7      c2     no     no     no     no     no  c2
8      no     c2     no     c2     no     no  c2
9      no     no     no     no     c2     no  c2
10     no     no     no     no     no     no  no
11     c3     no     c3     no     c3     no  c3
12     no     no     no     no     no     no  no
13     no     no     c3     c3     no     no  c3
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
2
0
225
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Используя max.col, мы можем извлечь первое значение в строке, которое не является "no". Поскольку каждая строка будет иметь одинаковое значение, отличное от «нет», связи здесь не будут иметь значения, или вы можете указать ties.method = "first", чтобы получить первое значение, отличное от «нет».

df$any <- df[cbind(1:nrow(df), max.col(df != "no"))]

df
#   Group1 Group2 Group3 Group4 Group5 Group6 any
#1      c1     no     no     c1     no     no  c1
#2      no     no     c1     no     no     no  c1
#3      no     no     no     no     c1     no  c1
#4      no     no     no     no     no     no  no
#5      c1     no     no     no     no     c1  c1
#6      no     c1     no     no     no     no  c1
#7      c2     no     no     no     no     no  c2
#8      no     c2     no     c2     no     no  c2
#9      no     no     no     no     no     no  no
#10     no     no     no     no     no     c2  c2
#11     c3     no     c3     no     c3     no  c3
#12     no     no     no     no     no     no  no
#13     no     no     c3     c3     no     no  c3

@DanM Можете ли вы объяснить это на примере? В каком случае будут значения, отличные от значения в столбце, и какой результат вы ожидаете в этих случаях?

Ronak Shah 22.05.2019 16:53

Мы можем использовать метод base R

df1$any <- apply(df1, 1, function(x) x[x != 'no'][1])
df1$any[is.na(df1$any)] <- "no"
df1$any
#[1] "c1" "c1" "c1" "no" "c1" "c1" "c2" "c2" "c2" "no" "c3" "no" "c3"

Или другой вариант с pmin в base R

df1$any <- do.call(pmin, df1)
df1$any
#[1] "c1" "c1" "c1" "no" "c1" "c1" "c2" "c2" "c2" "no" "c3" "no" "c3"

Или с dplyr

library(dplyr)
df1 %>% 
   mutate(any = pmin(!!! rlang::syms(names(.))))

Возможно, имеет смысл хранить ваши "no"s как пропущенные значения, и в этом случае дополнительный столбец — это все остальные столбцы coalesced

library(dplyr)

df %>% 
  mutate_all(na_if, 'no') %>% 
  mutate(any = reduce(., coalesce))

#    Group1 Group2 Group3 Group4 Group5 Group6  any
# 1      c1   <NA>   <NA>     c1   <NA>   <NA>   c1
# 2    <NA>   <NA>     c1   <NA>   <NA>   <NA>   c1
# 3    <NA>   <NA>   <NA>   <NA>     c1   <NA>   c1
# 4    <NA>   <NA>   <NA>   <NA>   <NA>   <NA> <NA>
# 5      c1   <NA>   <NA>   <NA>   <NA>     c1   c1
# 6    <NA>     c1   <NA>   <NA>   <NA>   <NA>   c1
# 7      c2   <NA>   <NA>   <NA>   <NA>   <NA>   c2
# 8    <NA>     c2   <NA>     c2   <NA>   <NA>   c2
# 9    <NA>   <NA>   <NA>   <NA>   <NA>   <NA> <NA>
# 10   <NA>   <NA>   <NA>   <NA>   <NA>     c2   c2
# 11     c3   <NA>     c3   <NA>     c3   <NA>   c3
# 12   <NA>   <NA>   <NA>   <NA>   <NA>   <NA> <NA>
# 13   <NA>   <NA>     c3     c3   <NA>   <NA>   c3

Другие вопросы по теме