Извлеките определенные столбцы из фрейма данных R

#r #dataframe #sapply

#r #фрейм данных #сапфировый

Вопрос:

Мой фрейм данных выглядит так:

 x s1 s2 s3 s4 1 x1 1 1954 1 yes 2 x2 2 1955 1 no 3 x3 1 1976 2 yes 4 x4 2 1954 2 yes 5 x5 3 1943 1 no  

Примеры данных:

 df lt;- data.frame(x=c('x1','x2','x3','x4','x5'),  s1=c(1,2,1,2,3),  s2=c(1954,1955,1976,1954,1943),   s3=c(1,1,2,2,1),  s4=c('yes','no','yes','yes','no'))```  

Можно ли извлечь столбцы фрейма данных, содержащие целые 1 числа, в 3 ? Например, новый фрейм данных будет выглядеть следующим образом:

 newdf  x s1 s3 1 x1 1 1 2 x2 2 1 3 x3 1 2 4 x4 2 2 5 x5 3 1  

Можно ли изменить столбцы s1 и s3 на 0 или 1 в зависимости от того, равно ли значение в столбце 1 или нет? Измененный фрейм данных будет выглядеть следующим образом:

 newdf2   x s1 s3 1 x1 1 1 2 x2 0 1 3 x3 1 0 4 x4 0 0 5 x5 0 1  

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

1. Вы говорите, что хотите извлечь столбцы, содержащие целые числа от 1 до 3, но затем сохраняете x переменную, содержащую строковые данные-хотите ли вы, чтобы там было другое правило? (Или x переменная-это просто специальная переменная, которую вы хотите сохранить?)

2. Переменная x — это просто особая переменная, которую я хотел бы сохранить!

Ответ №1:

основание R

 newdf lt;- df[, unique(c("x", names(which(sapply(df, function(z) is.numeric(z) amp; any(c(1, 3) %in% z)))))), drop = FALSE] newdf # x s1 s3 # 1 x1 1 1 # 2 x2 2 1 # 3 x3 1 2 # 4 x4 2 2 # 5 x5 3 1  newdf[-1] lt;- lapply(newdf[-1], function(z)  (z == 1)) newdf # x s1 s3 # 1 x1 1 1 # 2 x2 0 1 # 3 x3 1 0 # 4 x4 0 0 # 5 x5 0 1  

Проходной:

  • сначала мы определяем, какие столбцы являются числами и содержат числа 1 или 3:
     sapply(df, function(z) is.numeric(z) amp; any(c(1, 3) %in% z)) # x s1 s2 s3 s4  # FALSE TRUE FALSE TRUE FALSE   

    Это исключит любой столбец, который не является числовым, что означает, что character столбец, содержащий литерал "1" или "3" не будет сохранен. Это полный вывод с моей стороны; если вы хотите принять строковые версии, удалите is.numeric(z) компонент.

  • во-вторых, мы извлекаем имена тех, которые являются истинными, и добавляем "x"
     c("x", names(which(sapply(df, function(z) is.numeric(z) amp; any(c(1, 3) %in% z))))) # [1] "x" "s1" "s3"  
  • оберните это, unique(.) если по какой-то причине "x" оно также числовое и содержит 1 или 3 (этот шаг является чисто оборонительным, он может вам не понадобиться).
  • выберите эти столбцы, защитно добавив drop=FALSE , чтобы, если сопоставлен только один столбец, он все равно возвращал полный data.frame
  • замените только эти столбцы (исключая первый столбец, который является "x" ) на 0 или 1; z == 1 возврат logical и перенос (..) преобразуют логику в 0 (ложь) или 1 (истина).

dplyr

 library(dplyr) df %gt;%  select(x, where(~ is.numeric(.) amp; any(c(1, 3) %in% .))) %gt;%  mutate(across(-x, ~  (. == 1))) # x s1 s3 # 1 x1 1 1 # 2 x2 0 1 # 3 x3 1 0 # 4 x4 0 0 # 5 x5 0 1  

Ответ №2:

Я думаю, что это то, чего вы ожидали :

 my_df lt;- data.frame(x=c('x1','x2','x3','x4','x5'),  s1=c(1,2,1,2,3),  s2=c(1954,1955,1976,1954,1943),   s3=c(1,1,2,2,1),  s4=c('yes','no','yes','yes','no'))  my_df$end lt;- apply(my_df, 2, function(x) paste(x, collapse = " ")) my_df lt;- my_df %gt;% group_by(x) %gt;% mutate(end2 = paste(str_extract_all(string = end, pattern = "1|2|3", simplify = TRUE), collapse = " ")) my_var lt;- which(my_df$end == my_df$end2) my_df[, my_var] lt;- t(apply(my_df[, my_var], 1, function(x) ifelse(test = x == 1, yes = 1, no = 0))) my_df lt;- my_df[, c(1, my_var)]