繁体   English   中英

R:汇总多列(数字,字符)并删除NA

[英]R: summarise multiple column (numeric, character) and remove NAs

我有一个data.frame有很多列(~50)。 其中一些是字符,一些是数字,其中三个用于分组。

我需要:

  • 从数字列中删除NA
  • 计算每个数字列的平均值
  • 提取字符列的第一个元素

比方说,我们使用修改后的虹膜数据如下:

data(iris)
iris$year <- rep(c(2000,3000),each=25) ## for grouping
iris$color <- rep(c("red","green","blue"),each=50) ## character column
iris[1,] <- NA ## introducing NAs

我总共有~50列,数字和字符混合在一起。 我一直在尝试这样的事情:

giris <- group_by(iris, Species, year)
cls <- unlist(sapply(giris, class)) ## find out classes
action <- ifelse(cls == "numeric", "mean", "first")
action <- paste(action)
summarise_each(giris, action)

我得到的是对于组中所有列的意思,后面是具有相应组中的第一个值的列。 并且没有处理NAs ......这不是我寻求的......

帮助任何人?

你可以用试试这个if / elsefunssummarise_each

iris %>% 
  group_by(Species, year) %>% 
  summarise_each(funs(if(is.numeric(.)) mean(., na.rm = TRUE) else first(.)))

由于您在分组列中也有一些NA,因此您可以添加一个filter语句:

iris %>% 
  filter(!is.na(Species) & !is.na(year)) %>% 
  group_by(Species, year) %>% 
  summarise_each(funs(if(is.numeric(.)) mean(., na.rm = TRUE) else first(.)))
#Source: local data frame [6 x 7]
#Groups: Species [?]
#
#     Species  year Sepal.Length Sepal.Width Petal.Length Petal.Width color
#      (fctr) (dbl)        (dbl)       (dbl)        (dbl)       (dbl) (chr)
#1     setosa  2000        5.025    3.479167       1.4625       0.250   red
#2     setosa  3000        4.984    3.376000       1.4640       0.244   red
#3 versicolor  2000        6.012    2.776000       4.3120       1.344 green
#4 versicolor  3000        5.860    2.764000       4.2080       1.308 green
#5  virginica  2000        6.576    2.928000       5.6400       2.044  blue
#6  virginica  3000        6.600    3.020000       5.4640       2.008  blue

为了避免颜色列(或任何非数字列)中的潜在NA,您可以将其修改为first(na.omit(.))


你也可以尝试data.table

library(data.table)
setDT(iris)
iris[!is.na(Species) & !is.na(year), lapply(.SD, function(x) {
     if(is.numeric(x)) mean(x, na.rm = TRUE) else x[!is.na(x)][1L]}), 
     by = list(Species, year)]
#      Species year Sepal.Length Sepal.Width Petal.Length Petal.Width color
#1:     setosa 2000        5.025    3.479167       1.4625       0.250   red
#2:     setosa 3000        4.984    3.376000       1.4640       0.244   red
#3: versicolor 2000        6.012    2.776000       4.3120       1.344 green
#4: versicolor 3000        5.860    2.764000       4.2080       1.308 green
#5:  virginica 2000        6.576    2.928000       5.6400       2.044  blue
#6:  virginica 3000        6.600    3.020000       5.4640       2.008  blue

我试一试:

1.对于你提到的第一点,我会做类似下面的事情(第二点不需要):

na.omit(iris[ , which(sapply(iris, class) == "numeric")])

要将numericcharacter列分开,我使用以下内容:

iris[ , which(sapply(iris, class) == "numeric")]
iris[ , which(sapply(iris, class) == "character")]

2.第二项任务我将上面的行与colMeans结合起来:

colMeans(iris[ , which(sapply(iris, class) == "numeric")], na.rm = TRUE)

3.要提取字符列的第一个元素,您可以简单地执行:

iris[1, which(sapply(iris, class) == "character")]

在上面提到的虹膜数据的情况下,第一行是完全NA,甚至是字符列,所以我会迭代找到第一个非NA行

k <- 1
while(any(is.na(FirstCharacterElement <- iris[k, which(sapply(iris, class) == "character")]))){
  k <- k + 1
}

小心类因子(在iris数据的情况下分解代码,其中列Species是类因子,你可能期望它是一个字符列。你可以用sapply(iris, class)并更改它与例如

iris$Species <- as.character(iris$Species) #or with similar column names

当您读入数据时,您可以提及函数read.tableread.csv或类似的参数stringsAsFactors = FALSE

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM