Применить функцию к каждому столбцу в кадре данных, наблюдая за каждыми столбцами.

StackOverflow https://stackoverflow.com/questions/7303322

  •  25-10-2019
  •  | 
  •  

Вопрос

Я пытаюсь получить мин/макс для каждого столбца в большой кадре данных, как часть Знакомство с моими данными. Анкет Моя первая попытка была:

apply(t,2,max,na.rm=1)

Он рассматривает все как вектор символов, потому что первые несколько столбцов являются типами символов. Итак, максимум из некоторых численных столбцов выходит как " -99.5".

Затем я попробовал это:

sapply(t,max,na.rm=1)

Но это жалуется на Макс не имеет значения для факторов. (lapply то же самое.) Что меня сбивает с толку, так это то, что apply мысль max Был совершенно значимым для факторов, например, он вернул «зебру» для столбца 1.

Кстати, я посмотрел на Использование SAPPLY на векторе POSIXCT И один из ответов говорит "Когда вы используете Sapply, ваши объекты принуждаются к числовым, ...". Это то, что происходит со мной? тип.

Это было полезно?

Решение

Если бы это был «упорядоченный фактор», все было бы иначе. Что не значит, что мне нравятся «упорядоченные факторы», я не могу сказать, что некоторые отношения определены для «упорядоченных факторов», которые не определены для «факторов». Факторы рассматриваются как обычные категориальные переменные. Вы видите естественный порядок сортировки факторов, который является алфавитным лексическим порядком для вашего локали. Если вы хотите получить автоматическое принуждение к «цифровому» для каждого столбца, ... даты и факторы и все такое, тогда попробуйте:

sapply(df, function(x) max(as.numeric(x)) )   # not generally a useful result

Или если вы хотите сначала проверить факторы и вернуться, как вы ожидаете, тогда:

sapply( df, function(x) if("factor" %in% class(x) ) { 
            max(as.numeric(as.character(x)))
            } else { max(x) } )

Комментарий @Darrens работает лучше:

 sapply(df, function(x) max(as.character(x)) )  

max Достигается с векторами персонажей.

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

Причина, что max работает с apply в том, что apply Сначала принуждает свою кадр данных к матрице, а матрица может содержать только один тип данных. Таким образом, вы получите матрицу персонажей. sapply это просто обертка для lapply, Поэтому неудивительно, что оба дают одну и ту же ошибку.

Поведение по умолчанию при создании кадры данных предназначено для категориальных столбцов, которые должны храниться как факторы. Анкет Если вы не указаете, что это упорядоченный фактор, операции, как max а также min будет неопределенным, так как R предполагает, что вы создали неупорядоченный фактор

Вы можете изменить это поведение, указав options(stringsAsFactors = FALSE), который изменит по умолчанию для всего сеанса, или вы можете пройти stringsAsFactors = FALSE в data.frame() Строительный звонок сам. Обратите внимание, что это просто означает, что min а также max Примет «алфавитный» упорядочение по умолчанию.

Или вы можете вручную указать заказ для каждого фактора, хотя я сомневаюсь, что это то, что вы хотите сделать.

Несмотря на, sapply Как правило, даст атомный вектор, который во многих случаях будет влечет за собой конвертацию во многих случаях. Один из способов обойти это следующее:

#Some test data
d <- data.frame(v1 = runif(10), v2 = letters[1:10], 
                v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)

d[4,] <- NA

#Similar function to DWin's answer          
fun <- function(x){
    if(is.numeric(x)){max(x,na.rm = 1)}
    else{max(as.character(x),na.rm=1)}
}   

#Use colwise from plyr package
colwise(fun)(d)
         v1 v2       v3 v4
1 0.8478983  j 1.999435  J

Если вы хотите изучить свои данные summary (df) Обеспечивает мин, 1 -й квантиль, средний и средний, 3 -й квантильный и максимум численных колонн и частоту верхних уровней колонн факторов.

Строительство ответа @Ltamar:
Используйте резюме и сделайте вывод во что -то полезное!

library(tidyr)
library(dplyr)

df %>% 
  summary %>% 
  data.frame %>%
  select(-Var1) %>%
  separate(data=.,col=Freq,into = c('metric','value'),sep = ':') %>%
  rename(column_name=Var2) %>%
  mutate(value=as.numeric(value),
         metric = trimws(metric,'both') 
  ) %>%  
  filter(!is.na(value)) -> metrics

Это не красиво, и это, конечно, не быстро, но это выполняет работу!

Решение с использованием retype() От хаблара до факторов принуждения к характеру или числовому типу в зависимости от осуществимости. Я бы использовал dplyr Для применения максимума к каждому столбцу.

Код

library(dplyr)
library(hablar)

# Retype() simplifies each columns type, e.g. always removes factors
d <- d %>% retype()

# Check max for each column
d %>% summarise_all(max)

Результат

Не новые типы столбцов.

     v1 v2       v3 v4   
  <dbl> <chr> <dbl> <chr>
1 0.974 j      1.09 J   

Данные

# Sample data borrowed from @joran
d <- data.frame(v1 = runif(10), v2 = letters[1:10], 
                v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)

Абсолютный лучший способ сделать это - избежать базы *применять функции, которые принуждают весь кадр данных к массиву и используют colwise из плир. Анкет (Я удивлен, что никто об этом не упомянул)

Пример с использованием parse_guess как функция, которая работает на всех видах векторных данных:

colwise(parse_guess)(t)

Менее интересный ответ: мы можем применить на каждом столбце с помощью петли:

for (i in 1:nrow(t)) { t[, i] <- parse_guess(t[, i]) }

Я не знаю хорошего способа выполнение назначения с *применением при сохранении структуры кадра данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top