2013-11-25 4 views
1

Это должен быть основной вопрос, и может быть много дубликатов, но я не могу найти их, поэтому, пожалуйста, несите меня и указывайте мне в нужное место. Благодаря!привязка фреймов данных с различными типами данных

У меня есть кадр данных, который содержит целые числа с возможными NA и отсутствующие значения. Я вычисляю ряд строк (установка NA для нуля) и значение столбца (пропуск NA). Затем я хотел бы создать кадр данных (или таблицу), содержащий целые числа, вместе со строками и средствами столбца. Вот кадр пример данных:

df <- data.frame(
    'ID' = c("123A","456B","789C","1011","1213") 
    , 'Test 1' = c(55,65,60,NA,50) 
    , 'Test 2' = c(45,48,50,52,55) 
    , 'Test 3' = c(51,49,55,69,61) 
) 
df 
    ID Test.1 Test.2 Test.3 
1 123A  55  45  51 
2 456B  65  48  49 
3 789C  60  50  55 
4 1011  NA  52  69 
5 1213  50  55  61 

Вот функция, которая вычисляет столбец означает пропуск NAs:

colMean <- function(df, na.rm = TRUE) { 
    if (na.rm) { 
    n <- rowSums(!is.na(df)) 
    } else { 
    n <- ncol(df) 
    } 
    colMean <- colMeans(df, na.rm=na.rm) 
    return(rbind(df, "colMean" = colMean)) 
} 

Вот функция, которая вычисляет строки означает установление Nas к нулю:

rowMeanz <- function(df) { 
    df[is.na(df)] <- 0 
    return(cbind(df, "rowMean" = rowMeans(df))) 
} 

Одна из проблем заключается в том, что rbind изменяет тип данных в том смысле, что целые числа преобразуются в поплавки (или, как представляется,) в столбце с надписью «Test.1»:

colMean(df[sapply(df, is.numeric)]) 
     Test.1 Test.2 Test.3 
1   55.0  45  51 
2   65.0  48  49 
3   60.0  50  55 
4   NA  52  69 
5   50.0  55  61 
colMean 57.5  50  57 

В вашем ответе я был бы очень благодарен за объяснение, почему в этом случае влияет только первый столбец. Связано ли это с наличием NA в столбце?

я не наблюдал ту же проблему с другой функции, на основе cbind:

rowMeanz(df[sapply(df, is.numeric)]) 
    Test.1 Test.2 Test.3 rowMean 
1  55  45  51 50.33333 
2  65  48  49 54.00000 
3  60  50  55 55.00000 
4  0  52  69 40.33333 
5  50  55  61 55.33333 

В конце концов, я хотел бы получить dataframe или таблицу, которая будет выглядеть следующим образом:

ID Test.1 Test.2 Test.3 rowMean 
1 123A  55  45  51 50.33333 
2 456B  65  48  49 54.00000 
3 789C  60  50  55 55.00000 
4 1011  NA  52  69 40.33333 
5 1213  50  55  61 55.33333 
6 colMean 57.5 50  57 

Буду признателен, если вы покажете мне, как это сделать не слишком много. Я открыт для ответов на базовые R, а также ответы на основе пакетов. Эти вычисления будут сделаны онлайн в блестящем приложении, поэтому я бы особенно хотел видеть эффективные методы. Большое спасибо!

+2

'57.5' не является целым числом, поэтому ни один из элементов в этом столбце не может быть сохранен как целое. – joran

+0

Хорошо, я вижу, что теперь, ничего общего с НС, спасибо. Итак, что бы вы предложили «отображать» целые числа в виде целых чисел, а остальное - как float? Моя конечная цель - отобразить данные в виде таблицы. Благодарю. – PatrickT

ответ

1

Лучший, вероятно, чтобы преобразовать данные в формат символов в желаемом направлении, а затем положить кусочки вместе.

df <- data.frame(
    row.names = c("123A","456B","789C","1011","1213") 
    , 'Test 1' = c(55,65,60,NA,50) 
    , 'Test 2' = c(45,48,50,52,55) 
    , 'Test 3' = c(51,49,55,69,61) 
) 

colm <- colMeans(df, na.rm=TRUE) 
d0 <- df 
d0[is.na(d0)] <- 0 
rowm <- rowMeans(d0) 

dd <- format(df) 
dc <- formatC(colm, digits=1, format="f") 
dr <- formatC(rowm, digits=4, format="f") 
out <- cbind(rbind(dd, colMeans=dc), rowMeans=c(dr, "")) 
print(out, right=FALSE) 

##   Test.1 Test.2 Test.3 rowMeans 
## 123A  55  45  51  50.3333 
## 456B  65  48  49  54.0000 
## 789C  60  50  55  55.0000 
## 1011  NA  52  69  40.3333 
## 1213  50  55  61  55.3333 
## colMeans 57.5 50.0 57.0  
+0

Спасибо, Аарон, это именно то, что я искал. – PatrickT

+0

Если вы хотите, чтобы десятичные разряды выстроились в линию, попробуйте использовать параметр 'width' в' formatC'. – Aaron

+0

Спасибо Аарону, теперь, когда я знаю о формате и форматеC, я могу найти страницы справки. Огромное спасибо. – PatrickT

1

Не уверен, что, если мое решение будет особенно полезно на ваш вопрос, но ниже мой подход:

df <- data.frame(
    'Test 1' = c(55,65,60,NA,50), 
    'Test 2' = c(45,48,50,52,55), 
    'Test 3' = c(51,49,55,69,61) 
) 

#First, it might be a good idea to set the id as the rownames. 
rownames(df) <- c("123A","456B","789C","1011","1213") 

#Calculate the col and row means 
colMean <- apply(df, 2, function(x) mean(x, na.rm = T)) 
df$rowMean <- apply(df, 1, function(x) mean(x, na.rm = T)) 
df <- rbind(df, colMeans) 
rownames(df)[nrow(df)] <- "colMean" 
+0

Hi jinlong, я выбрал ответ Аарона, потому что он был легче адаптирован к моей ситуации. Благодаря! – PatrickT

0

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

Данные:

df <- data.frame(
    'ID' = c("123A","456B","789C","1011","1213") 
    , 'Test 1' = c(13,8,14,NA,15) 
    , 'Test 2' = c(13,4,16,7,12) 
    , 'Test 3' = c(15,9,13,6,13) 
) 

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

colMean <- function(df, na.rm = TRUE) {# either remove or annull NAs 
    if (!na.rm) {# annull NAs 
    df[is.na(df)] <- 0 
    } 
    colMean <- colMeans(df, na.rm=na.rm) 
    return(colMean) 
} 
rowMean <- function(df, na.rm = TRUE) {# either remove or annull NAs 
    if (!na.rm) {# annull NAs 
    df[is.na(df)] <- 0 
    } 
    rowMean <- rowMeans(df, na.rm=na.rm) 
    return(rowMean) 
} 
rowSd <- function(df, na.rm = TRUE) {# either remove or annull NAs 
    if (na.rm) {# remove NAs 
    n <- rowSums(!is.na(df)) 
    } else { 
    df[is.na(df)] <- 0 
    n <- ncol(df) 
    } 
    rowMean <- rowMeans(df, na.rm=na.rm) 
    rowVar <- rowMeans(df*df, na.rm=na.rm) - (rowMeans(df, na.rm=na.rm))^2 
    rowSd <- sqrt(rowVar * n/(n-1)) 
    return(rowSd) 
} 
colSd <- function(df, na.rm = TRUE) {# either remove or annull NAs 
    if (na.rm) {# remove NAs 
    n <- colSums(!is.na(df)) 
    } else { 
    df[is.na(df)] <- 0 
    n <- nrow(df) 
    } 
    colMean <- colMeans(df, na.rm=na.rm) 
    colVar <- colMeans(df*df, na.rm=na.rm) - (colMeans(df, na.rm=na.rm))^2 
    colSd <- sqrt(colVar * n/(n-1)) 
    return(colSd) 
} 

Реферат как функция dataframe 'df', статистика столбцов «col», статистика «вдоль строки» и «pad padding». Символу «pad» можно было бы установить пустую ячейку с «» или установить в NA или что-то еще. По умолчанию NA удаляются по столбцам, но по умолчанию по умолчанию задаются равными нулю.

summ <- function(df 
    , col = list("colMean" = colMean) 
    , row = list("rowMean" = rowMean) 
    , pad = NA_character_) 
{ 
    dfN <- df[sapply(df, is.numeric)] 
    colN <-lapply(col, function(x){formatC(x(dfN, na.rm = TRUE), 'digits' = 1, 'format' = "f")}) 
    rowN <-lapply(row, function(x){formatC(x(dfN, na.rm = FALSE), 'digits' = 1, 'format' = "f")}) 
    pad <- rep(pad,'length' = length(colN)) 
    out <- cbind(rbind(format(dfN),do.call(rbind,colN)), lapply(rowN,function(x){c(x,pad)})) 
    return(print(out, 'right' = FALSE)) 
} 

Примеры использования:

c <- list("colMean" = colMean, "colSd" = colSd) 
r <- list("rowMean" = rowMean, "rowSd" = rowSd) 
summ(df) 
summ(df,c,r) 
summ(df,'col'=c,'row'=r) 
summ(df,'col'=c,'row'=r, 'pad'="X") 
     Test.1 Test.2 Test.3 rowMean rowSd 
1  13  13  15  13.7 1.2 
2  8  4  9  7.0  2.6 
3  14  16  13  14.3 1.5 
4  NA  7  6  4.3  3.8 
5  15  12  13  13.3 1.5 
colMean 12.5 10.4 11.2 X  X 
colSd 3.1 4.8 3.6 X  X 

Естественно, не стесняйтесь комментировать. Благодаря!

Смежные вопросы