#r #na
#r #na
Вопрос:
В вопросах с множественным выбором, которые я должен проанализировать, есть опция «другое». Для тех, кто может выбрать только один вариант, я буду объединять отдельные столбцы каждого варианта ответа в 1 столбец с помощью unite . Везде, где пользователь написал в строке «другое», вместо выбора одного из предоставленных вариантов я хочу изменить эту строку на «Другое».
Например:
ID Sector1 Sector2 Sector3 .... Sector13(Other)
A NA NA "String3" NA
B "String1" NA NA NA
C "String1" NA NA NA
D NA NA NA "Other string1"
E NA NA NA "Other string2"
ID NewSectorColumn
A "String3"
B "String1"
C "String1"
D "Other"
E "Other"
Вот мой код:
Сначала я создаю новую переменную ($SectorOther) в RawData1, затем изменяю значения $ SectorOther на «Other», если $Sector13 (столбец, содержащий все «другие» ответы) не является пустым.
rawdata1$SectorOther <- rawdata1$sector13
rawdata1$SectorOther [which(!is.na(rawdata1$SectorOther))] <- "Other Sector"
Просто интересно, есть ли более элегантное решение, где я мог бы объединить выполнение того же самого с несколькими другими переменными, подобными этой.
Ответ №1:
Возможно, вы можете использовать apply()
встроенную функцию and для организации вашего кода таким образом. grepl()
Функция направлена на обнаружение строки с other
помощью word . Здесь код:
#Code
myfun <- function(x)
{
y <- x[min(which(!is.na(x)))]
y <- ifelse(grepl('other',y,ignore.case = T),'Other',y)
return(y)
}
#Apply
df$Newvar <- apply(df[,-1],1,myfun)
Вывод:
df
ID Sector1 Sector2 Sector3 Sector13.Other. Newvar
1 A <NA> NA String3 <NA> String3
2 B String1 NA <NA> <NA> String1
3 C String1 NA <NA> <NA> String1
4 D <NA> NA <NA> Other string1 Other
5 E <NA> NA <NA> Other string2 Other
Некоторые используемые данные:
#Data
df <- structure(list(ID = c("A", "B", "C", "D", "E"), Sector1 = c(NA,
"String1", "String1", NA, NA), Sector2 = c(NA, NA, NA, NA, NA
), Sector3 = c("String3", NA, NA, NA, NA), Sector13.Other. = c(NA,
NA, NA, "Other string1", "Other string2")), row.names = c(NA,
-5L), class = "data.frame")
Комментарии:
1. Спасибо! Просто просматриваю код, чтобы убедиться, что я его понимаю: в функции новая переменная «y» создается для минимальной строки, где «x» имеет значение (т. Е. Не NA). Затем, когда grepl находит строку в (y), содержащую «other», он превращает «y» в символьную строку «other», игнорируя регистр. Если он не находит ее, он оставляет ее нетронутой. Затем в функции apply: вы применяете ее ко всему фрейму данных. 1 вопрос: не должен ли y начинаться для всех значений x (отсутствует или нет?) другая вещь, которую я забыл упомянуть: у меня есть несколько из них в моем df, поэтому применить все не сработает
2. @Pre Применяется ко всем значениям в каждой строке фрейма данных. Возможно, если вы сможете добавить еще один образец данных для тестирования или корректировки кода, это было бы прекрасно!
Ответ №2:
В базе R вы могли бы сделать:
indices <- cbind(1:nrow(df),max.col(!is.na(df[-1]), 'first'))
df$New_col <- sub('(Other).*', '\1', df[-1][indices])
df
ID Sector1 Sector2 Sector3 Sector13.Other. New_col
1 A <NA> NA String3 <NA> String3
2 B String1 NA <NA> <NA> String1
3 C String1 NA <NA> <NA> String1
4 D <NA> NA <NA> Other string1 Other
5 E <NA> NA <NA> Other string2 Other
другой вариант — использовать `объединить from
dplyr`:
df$NewSectorColumn <- sub("(Other).*","\1",dplyr::coalesce(!!!df[-1]))
df
ID Sector1 Sector2 Sector3 Sector13.Other. NewSectorColumn
1 A <NA> NA String3 <NA> String3
2 B String1 NA <NA> <NA> String1
3 C String1 NA <NA> <NA> String1
4 D <NA> NA <NA> Other string1 Other
5 E <NA> NA <NA> Other string2 Other
Ответ №3:
Вариант с fcoalecse
from data.table
library(data.table)
setDT(df)[, NewSectorColumn := sub("\s .*", "",
do.call(fcoalesce, lapply(.SD, as.character))),
.SDcols = patterns('^Sector')]
-вывод
df
# ID Sector1 Sector2 Sector3 Sector13.Other. NewSectorColumn
#1: A <NA> NA String3 <NA> String3
#2: B String1 NA <NA> <NA> String1
#3: C String1 NA <NA> <NA> String1
#4: D <NA> NA <NA> Other string1 Other
#5: E <NA> NA <NA> Other string2 Other
данные
df <- structure(list(ID = c("A", "B", "C", "D", "E"), Sector1 = c(NA,
"String1", "String1", NA, NA), Sector2 = c(NA, NA, NA, NA, NA
), Sector3 = c("String3", NA, NA, NA, NA), Sector13.Other. = c(NA,
NA, NA, "Other string1", "Other string2")), row.names = c(NA,
-5L), class = "data.frame")