R 如何将多个二进制文件转换为分类文件

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

我想将多个二进制列转换为一个列,其中包含基于二进制列的行名的分类内容。我曾尝试在其他方面使用此论坛中的代码,但由于我的情况不同,有些行没有条目,因此我没有找到有效的解决方案。这里提出的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,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" ""  ""  ""  ""