2013-11-25 86 views
1

这应该是一个基本问题,可能有重复,但我似乎无法找到它们,所以请耐心等待并指给我正确的位置。谢谢!不同数据类型的绑定数据帧

我有一个数据框,包含可能的NA和缺失值的整数。我正在计算行方式(将NAs设置为零),列方式(跳过NAs)。然后,我想创建一个包含整数的数据框架(或表格)以及行方式和列方式。下面是一个例子的数据帧:

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 

这里是计算列中的功能意味着跳过的NA:

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)) 
} 

这里是计算行装置设定的NA到零功能:

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 

最后,我想获得数据帧或表是这样的:

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

好的,我现在看到,与NA无关,谢谢。那么你会如何建议将整数显示为整数,其余部分是浮点数?我的最终目的是将数据显示在表格中。谢谢。 – 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

谢谢Aaron,那正是我正在寻找的东西。 – PatrickT

+0

如果您想要小数位排列,请尝试在'formatC'中使用'width'参数。 – Aaron

+0

感谢Aaron,现在我知道格式和formatC,我可以查看帮助页面。很好的回答谢谢。 – 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

嗨金龙,我选择了亚伦的答案,因为它更容易适应我的情况。谢谢! – PatrickT

0

我想跟进我如何使用Aaron的建议来生成汇总数据的表。应该很容易扩展到其它的统计信息,如最小值,最大值,歪斜等。

数据:

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) 
} 
:即计算用于汇总数据统计

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) 
) 

几个功能

作为dataframe'df',沿列统计信息'col',沿行'统计信息'和填充字符'pad'的函数的摘要。 'pad'字符可以被设置为一个空单元格,用“”或设置为NA或其他。默认情况下,NAs沿列排除,但默认设置为零。用法

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 

自然,随意评论。谢谢!