R 如何将多个二进制文件转换为分类文件
我想将多个二进制列转换为一个列,其中包含基于二进制列的行名的分类内容。我曾尝试在其他方面使用此论坛中的代码,但由于我的情况不同,有些行没有条目,因此我没有找到有效的解决方案。这里提出的dplyr解决方案在我的数据集上运行缓慢。我的数据集有超过200万行 这是数据R 如何将多个二进制文件转换为分类文件,r,vector,dplyr,R,Vector,Dplyr,我想将多个二进制列转换为一个列,其中包含基于二进制列的行名的分类内容。我曾尝试在其他方面使用此论坛中的代码,但由于我的情况不同,有些行没有条目,因此我没有找到有效的解决方案。这里提出的dplyr解决方案在我的数据集上运行缓慢。我的数据集有超过200万行 这是数据 m <- matrix(0,10,10) colnames(m) <- c("a","b","c","d","e","f","g","h","i","j") m[3,2] <- 1 m[4,8] <- 1 m[5
m <- matrix(0,10,10)
colnames(m) <- c("a","b","c","d","e","f","g","h","i","j")
m[3,2] <- 1
m[4,8] <- 1
m[5,8] <- 1
m[6,1] <- 1
我想去
colname
[1,] ""
[2,] ""
[3,] "b"
[4,] "h"
[5,] "h"
[6,] "a"
[7,] "d"
[8,] ""
[9,] ""
[10,] ""
这应该是快速借用Ronak的提示并使用ties.method=first 一般来说,矩阵比数据帧快得多。与所有矩阵操作相比,将矩阵转换为数据帧以使用dplyr将非常缓慢 还有一种可能性:
nm = colnames(m)
apply(m, 1, function(x) if (any(x == 1)) nm[which.max(x)] else "")
max.col解决方案速度非常快,尤其是Ronak的,在2M x 325矩阵上占用我的笔记本电脑不到5秒:
## Generate data
nm = combn(letters, 2, FUN = paste, collapse = "")
nr = 2e6
nc = length(nm)
m = matrix(0, nrow = nr, ncol = nc)
n_ones = 1.5e6
ones = cbind(sample(1:nr, size = n_ones), sample(1:nc, size = n_ones, replace = TRUE))
m[ones] = 1
system.time(
{r1 = apply(m, 1, function(x) if (any(x == 1)) nm[which.max(x)] else "")}
)
# user system elapsed
# 13.94 3.87 19.50
system.time({
mc = max.col(m, ties.method = "first")
r2 = ifelse(m[cbind(1:nrow(m), mc)] == 0, "", nm[mc])
})
# user system elapsed
# 3.56 0.01 3.72
# Ronak's solution
system.time({
cols <- max.col(m, ties.method = "first")
vec <- colnames(m)[cols]
vec[cols == 1 & m[, 1] != 1] <- ''
})
# user system elapsed
# 3.16 0.00 3.31
max.col解决方案比apply快得多,Ronak的优化使它非常好。这应该是从Ronak那里快速借用一个提示,并首先使用ties.method=first 一般来说,矩阵比数据帧快得多。与所有矩阵操作相比,将矩阵转换为数据帧以使用dplyr将非常缓慢 还有一种可能性:
nm = colnames(m)
apply(m, 1, function(x) if (any(x == 1)) nm[which.max(x)] else "")
max.col解决方案速度非常快,尤其是Ronak的,在2M x 325矩阵上占用我的笔记本电脑不到5秒:
## Generate data
nm = combn(letters, 2, FUN = paste, collapse = "")
nr = 2e6
nc = length(nm)
m = matrix(0, nrow = nr, ncol = nc)
n_ones = 1.5e6
ones = cbind(sample(1:nr, size = n_ones), sample(1:nc, size = n_ones, replace = TRUE))
m[ones] = 1
system.time(
{r1 = apply(m, 1, function(x) if (any(x == 1)) nm[which.max(x)] else "")}
)
# user system elapsed
# 13.94 3.87 19.50
system.time({
mc = max.col(m, ties.method = "first")
r2 = ifelse(m[cbind(1:nrow(m), mc)] == 0, "", nm[mc])
})
# user system elapsed
# 3.56 0.01 3.72
# Ronak's solution
system.time({
cols <- max.col(m, ties.method = "first")
vec <- colnames(m)[cols]
vec[cols == 1 & m[, 1] != 1] <- ''
})
# user system elapsed
# 3.16 0.00 3.31
max.col解决方案比apply快得多,Ronak的优化使其非常好。使用max.col的另一种方法是在每行中指定ties.method=首先获取max元素的索引,并获取相应的列名。然后,我们可以将列名称替换为空,该列将max.col值返回为1第1列,但在m的第一列中没有1
使用max.col的另一种方法是获取每行中指定ties.method=first的max元素的索引,并获取相应的列名。然后,我们可以将列名称替换为空,该列将max.col值返回为1第1列,但在m的第一列中没有1
不错,只看第一列可能比我更复杂的索引要快一点。避免ifelse也很好。好吧,我真的很震惊-速度的大幅提升是由于ties.method=first,这使得昂贵的max.col运算快了大约5倍。也许ties.method=first必须跳过一些计算,这会使它更快。很好,只看第一列可能比我更复杂的索引要快一点。避免ifelse也很好。好吧,我真的很震惊——速度的大幅提升是由于ties.method=first,这使得昂贵的max.col运算快了约5倍。也许ties.method=first必须跳过一些计算,从而使它更快。
cols <- max.col(m, ties.method = "first")
vec <- colnames(m)[cols]
vec[cols == 1 & m[, 1] != 1] <- ''
#[1] "" "" "b" "h" "h" "a" "" "" "" ""