我正在尝试获取大型数据框中每列的最小值/最大值,作为了解我的数据的一部分。我的第一次尝试是:
apply(t,2,max,na.rm=1)
它将所有内容视为字符向量,因为前几列是字符类型。因此,一些数字列的最大值将以" -99.5"
形式出现。
然后我尝试了这个:
sapply(t,max,na.rm=1)
但它抱怨最大因素没有意义。 (lapply
是一样的。)令我困惑的是,apply
认为max
对于因素非常有意义,例如:它为第1列返回了“ZEBRA”。
顺便说一句,我看了一下Using sapply on vector of 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)
提供min,1st分位数,中位数和平均数,第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
它不漂亮,肯定不会很快,但它完成了工作!