Подсчет количества строк, в которых значение встречается хотя бы один раз во многих столбцах

#r #for-loop #dplyr

#r #для цикла #dplyr

Вопрос:

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

У меня есть data.frame с именем df_sel, содержащий 5064 строки и 215 столбцов.

Некоторые столбцы (~ 80) содержат целые числа с уникальным идентификатором для определенного признака (лекарства). Эти столбцы называются «meds_0_1», «meds_0_2», «meds_0_3» и т.д., А также «meds_1_1», «meds_1_2», «meds_1_3». Каждый столбец может содержать или не содержать какие-либо целочисленные значения, которые я ищу.

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

 metformin = 1140884600  # not grouped
sulfonylurea = c(1140874718, 1140874724, 1140874726) # grouped
  

Если бы можно было найти группу лекарств, например, в векторном формате, как указано выше, это было бы полезно.

Я хотел бы сделать это:

 IF [a specific row] 
CONTAINS [the single integer value of interest] 
IN [any of the columns within the df starting with "meds_0"] 
A_NEW_VARIABLE_METFORMIN = 1 ELSE A_NEW_VARIABLE_METFORMIN = 0
  

и соответственно

 IF [a specific row] 
CONTAINS [any of multiple integer values of interest] 
IN [any of the columns within the df starting with "meds_0"] 
A_NEW_VARIABLE_SULFONYLUREA = 1 ELSE A_NEW_VARIABLE_SULFONYLUREA = 0
  

Я научился создавать вектор на основе имен столбцов:

 column_names <- names(df_sel) %>% str_subset('^meds_0')
  

Но я не продвинулся дальше, несмотря на некоторые предложения ниже.

Я надеюсь, вы лучше понимаете, что я пытаюсь сделать.

Ответ №1:

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

 library(stringr)
column_names <- names(df_sel) %>% 
  str_subset('^meds_0')

relevant_df <- df_sel %>%
  select(column_names)
  

Я не совсем понял структуру ваших переменных (если они являются целыми числами, логическими числами и т.д.), Поэтому я не уверен, как продолжить, но это, вероятно, будет включать что-то вроде суммирования по всем столбцам и удаления тех, которые не равны 0, например:

 meds_taken <- rowSums(relevant_df)
df_sel_med_count <- df_sel %>% 
  add_column(meds_taken)
  

На этом этапе у вас должен быть ваш начальный df с соответствующими данными в одном столбце, и вы можете суммировать по предмету, лекарству или чему-либо еще любым удобным для вас способом.

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

Комментарии:

1. Я ценю вашу помощь! Регулярное выражение для получения имен столбцов работает идеально, все соответствующие столбцы извлекаются в вектор. Однако, когда я создаю relevant_df с использованием предоставленного вами кода, он выдает мне только один столбец (первый в column_names ) со всеми строками.

2. Это из-за опечатки! Извините. Я набрал select_ , когда это должно было быть select . Сейчас я отредактирую ответ.

3. Я пытался, но новая переменная, созданная и добавленная в df, подсчитывает значения, а не количество вхождений. Я обновляю вопрос dmy выше, чтобы лучше объяснить мой вопрос.

Ответ №2:

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

Хотя tidyverse является наиболее широко приемлемым и «простым» методом, я бы рекомендовал в данном случае использовать «lapply», поскольку это чрезвычайно быстро. Ваш код с точки зрения программирования становится простым логическим значением, как вы заявили, но я думаю, что мы можем пойти немного дальше. Использование встроенных данных из ‘mtcars’,

 data(mtcars)
head(mtcars, 6)
target=6

#trues and falses for each row and column

rows=lapply(mtcars, function(x) x %in% target)

#Number of Trues for each column and which have more that 0 Trues

column_sums=unlist(lapply(rows, function(x) (sum(x, na.rm = TRUE))))
which(column_sums>0)
  

Это будет работать с другими типами данных с некоторыми изменениями здесь и там.

Комментарии:

1. Спасибо за совет по Bioconductor, проверю. Ваш ответ приблизил меня к моей цели, пожалуйста, смотрите Редактирование выше!

2. Если я ответил на ваш вопрос, пожалуйста, проголосуйте и задайте другой вопрос, а не добавляйте больше задач к вашему первоначальному вопросу. Вы также можете обратиться ко мне за работой и контрактами, связанными с R.