题
我正在尝试在大型数据框中获得每列的最小/最大,作为的一部分 了解我的数据. 。我的第一次尝试是:
apply(t,2,max,na.rm=1)
它将所有内容视为字符向量,因为前几列是字符类型。因此,某些数字列的最大是 " -99.5"
.
然后,我尝试了:
sapply(t,max,na.rm=1)
但是它抱怨 最大因素没有意义. (lapply
是一样的。)令我困惑的是 apply
想法 max
对于因素是完全有意义的,例如,它返回了第1列的“斑马”。
顺便说一句,我看了看 在Posixct的向量上使用sapply 其中一个答案说”当您使用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)
提供最小,第一分位数,中值和平均值,数值列的第三分位数和最大值以及因子列的最高级别的频率。
建立 @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()
从HABLAR到胁迫因素到性格或数字类型,具体取决于可行性。我会用 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
从 plyr. 。 (我很惊讶没有人提到这一点)
示例使用 parse_guess
作为在各种向量数据类型上运行的函数:
colwise(parse_guess)(t)
不太有趣的答案:我们可以使用循环的每一列申请:
for (i in 1:nrow(t)) { t[, i] <- parse_guess(t[, i]) }
我不知道一种很好的方式 在保存数据框架结构时使用 *使用 *申请.