Помещение содержимого многих столбцов в новый отдельный столбец - PullRequest
1 голос
/ 15 января 2020

Спасибо за ответы на мой предыдущий вопрос, но мне нужно обновить его, поскольку решения не работают с моим реальным примером, т. Е. С фреймом данных 3170x11.

Позвольте мне кратко повторить его. У меня есть фрейм данных 3170X11, заполненный терминами «Нормал», «Делезиони» или NA. Я хотел бы объединить результаты столбца в новые столбцы, сообщая о типе сообщаемого термина, который действительно является «нормальским», «делезионским» или «NA». Если 'Normale' и 'NA' присутствуют в одном ряду, следует указать 'Normale'. Если «Delezioni» и «NA» присутствуют в одном ряду, следует указать «Delezioni». В случае присутствия только «NA» следует указать «NA». Однако, если присутствуют и «Нормали», и «Делезиони», следует указать «Ошибка». Акрун и другие сообщили о хорошем решении ( Объединение многих столбцов в один столбец ), но, как я уже сказал, не работает, когда все становится больше:

library (RCurl)
a <- getURL('http://download1645.mediafire.com/pp9z3okh5tgg/96px8ophovxrxe9/example.tab')
df2 <- read.table(text=a,header=TRUE, sep = "\t")
df2 <- data.frame(lapply(df2, as.character), stringsAsFactors=FALSE) #converts from factor to character
res <- df2 %>%
   mutate_if(~ all(is.na(.)) && is.logical(.), ~ NA_character_) %>%
   transmute(Summary = case_when(rowSums(!is.na(.)) > 1 ~ "Error",
            TRUE ~ coalesce(!!! .)))

res содержит несколько ошибок , Например, первые строки должны быть:

  Summary
1   Normale
2    <NA>
3    <NA>
4    <NA>
5   Normale
6   Normale

Вместо них:

> head (res)
  Summary
1   Error
2    <NA>
3    <NA>
4    <NA>
5   Error
6   Error 

Спасибо

Ответы [ 2 ]

2 голосов
/ 15 января 2020

Следующее работает для меня, с набором данных в ссылке.

f1 <- function(x){
  y <- unique(x[!is.na(x)])
  if(length(y) == 0) 
    NA 
  else if(length(y) == 1) 
    y 
  else "Error"
}

df2$Summary <- apply(df2, 1, f1)

И без необходимости внешних пакетов, только база R.

1 голос
/ 15 января 2020

Я думаю, вы можете определить простую функцию, которая работает на основе ваших требований

apply_fun <- function(x) {
  if(all(c("Delezioni","Normale") %in% x)) return('Error')
  if("Delezioni" %in% x) return('Delezioni')
  if("Normale" %in% x)  return('Normale')
  else NA
}

, а затем apply по строкам

example$answer <- apply(example, 1, apply_fun)
head(example$answer)
#[1] "Normale" NA        NA        NA        "Normale" "Normale"

При необходимости tidyverse / dplyr ответ, мы можем преобразовать эти несколько if операторов в case_when и затем использовать pmap

library(tidyverse)

apply_fun <- function(x) {
  case_when(all(c("Delezioni","Normale") %in% x) ~ "Error", 
            "Delezioni" %in% x ~ "Delezioni", 
            "Normale" %in% x ~ "Normale", 
            TRUE ~NA_character_)
}

output <- example %>% mutate(answer = pmap_chr(., ~apply_fun(c(...))))
...