Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
替换dataframe中多列中的值_R_Performance_Loops - Fatal编程技术网

替换dataframe中多列中的值

替换dataframe中多列中的值,r,performance,loops,R,Performance,Loops,在下面的示例中,res有90行6列,包括几个NAs。还有一个矩阵,tmpCombs,有6行2列。tmpcomb的每一行对应于res中的一组15行(6*15=90)。它的列数(2)意味着我必须用指定的字符(如“B”)替换res每行中的2个现有NA。(确保每行至少有2个NAs) 例如,tmpCombs的第5行中的值2和4意味着对于res的组61-75(4*15+1):(5*15)中的每一行,出现的第2和第4个NAs必须替换为“B” 我可以使用嵌套for循环来完成这项工作,但我正在寻找一种更快/更大规

在下面的示例中,
res
有90行6列,包括几个NAs。还有一个矩阵,
tmpCombs
,有6行2列。
tmpcomb
的每一行对应于
res
中的一组15行(6*15=90)。它的列数(2)意味着我必须用指定的字符(如“B”)替换
res
每行中的2个现有NA。(确保每行至少有2个NAs)

例如,
tmpCombs
的第5行中的值2和4意味着对于
res
的组61-75
(4*15+1):(5*15)
中的每一行,出现的第2和第4个NAs必须替换为“B”

我可以使用嵌套for循环来完成这项工作,但我正在寻找一种更快/更大规模的方法来执行这些替换(可能使用
dplyr
data.table
),因为随着维度的增加,我的代码变得越来越慢

下面给出了
res
tmpCombs
的示例。还有第二个数据帧,
res2
,其中包含所需的输出

res <- structure(list(X1 = c("A", "A", "A", "A", "A", NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, "A", "A", "A", "A", "A", NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, "A", "A", "A", "A", "A", NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, "A", "A", "A", "A", "A", NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, "A", "A", "A", "A", "A", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "A", "A", "A", "A", "A", 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X2 = c("A", NA, NA, 
NA, NA, "A", "A", "A", "A", NA, NA, NA, NA, NA, NA, "A", NA, 
NA, NA, NA, "A", "A", "A", "A", NA, NA, NA, NA, NA, NA, "A", 
NA, NA, NA, NA, "A", "A", "A", "A", NA, NA, NA, NA, NA, NA, "A", 
NA, NA, NA, NA, "A", "A", "A", "A", NA, NA, NA, NA, NA, NA, "A", 
NA, NA, NA, NA, "A", "A", "A", "A", NA, NA, NA, NA, NA, NA, "A", 
NA, NA, NA, NA, "A", "A", "A", "A", NA, NA, NA, NA, NA, NA), 
    X3 = c(NA, "A", NA, NA, NA, "A", NA, NA, NA, "A", "A", "A", 
    NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, NA, "A", "A", 
    "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, NA, "A", 
    "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, NA, 
    "A", "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, 
    NA, NA, "A", "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", 
    NA, NA, NA, "A", "A", "A", NA, NA, NA), X4 = c(NA, NA, "A", 
    NA, NA, NA, "A", NA, NA, "A", NA, NA, "A", "A", NA, NA, NA, 
    "A", NA, NA, NA, "A", NA, NA, "A", NA, NA, "A", "A", NA, 
    NA, NA, "A", NA, NA, NA, "A", NA, NA, "A", NA, NA, "A", "A", 
    NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, "A", NA, NA, "A", 
    "A", NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, "A", NA, NA, 
    "A", "A", NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, "A", 
    NA, NA, "A", "A", NA), X5 = c(NA, NA, NA, "A", NA, NA, NA, 
    "A", NA, NA, "A", NA, "A", NA, "A", NA, NA, NA, "A", NA, 
    NA, NA, "A", NA, NA, "A", NA, "A", NA, "A", NA, NA, NA, "A", 
    NA, NA, NA, "A", NA, NA, "A", NA, "A", NA, "A", NA, NA, NA, 
    "A", NA, NA, NA, "A", NA, NA, "A", NA, "A", NA, "A", NA, 
    NA, NA, "A", NA, NA, NA, "A", NA, NA, "A", NA, "A", NA, "A", 
    NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, "A", NA, "A", NA, 
    "A"), X6 = c(NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, 
    "A", NA, "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", 
    NA, NA, "A", NA, "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, 
    "A", NA, NA, "A", NA, "A", "A", NA, NA, NA, NA, "A", NA, 
    NA, NA, "A", NA, NA, "A", NA, "A", "A", NA, NA, NA, NA, "A", 
    NA, NA, NA, "A", NA, NA, "A", NA, "A", "A", NA, NA, NA, NA, 
    "A", NA, NA, NA, "A", NA, NA, "A", NA, "A", "A")), .Names = c("X1", 
"X2", "X3", "X4", "X5", "X6"), row.names = c(NA, -90L), class = "data.frame")

tmpCombs <- structure(c(1L, 1L, 1L, 2L, 2L, 3L, 2L, 3L, 4L, 3L, 4L, 4L), .Dim = c(6L, 
2L))

res2 <- structure(list(X1 = c("A", "A", "A", "A", "A", "B", "B", "B", 
"B", "B", "B", "B", "B", "B", "B", "A", "A", "A", "A", "A", "B", 
"B", "B", "B", "B", "B", "B", "B", "B", "B", "A", "A", "A", "A", 
"A", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "A", "A", 
"A", "A", "A", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "A", "A", 
"A", "A", "A", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "A", "A", 
"A", "A", "A", NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), X2 = c("A", 
"B", "B", "B", "B", "A", "A", "A", "A", "B", "B", "B", "B", "B", 
"B", "A", "B", "B", "B", "B", "A", "A", "A", "A", NA, NA, NA, 
NA, NA, NA, "A", "B", "B", "B", "B", "A", "A", "A", "A", NA, 
NA, NA, NA, NA, NA, "A", NA, NA, NA, NA, "A", "A", "A", "A", 
"B", "B", "B", "B", "B", "B", "A", NA, NA, NA, NA, "A", "A", 
"A", "A", "B", "B", "B", "B", "B", "B", "A", NA, NA, NA, NA, 
"A", "A", "A", "A", NA, NA, NA, NA, NA, NA), X3 = c("B", "A", 
"B", "B", "B", "A", "B", "B", "B", "A", "A", "A", NA, NA, NA, 
"B", "A", NA, NA, NA, "A", NA, NA, NA, "A", "A", "A", "B", "B", 
"B", "B", "A", NA, NA, NA, "A", NA, NA, NA, "A", "A", "A", NA, 
NA, NA, NA, "A", "B", "B", "B", "A", "B", "B", "B", "A", "A", 
"A", "B", "B", "B", NA, "A", "B", "B", "B", "A", "B", "B", "B", 
"A", "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, 
NA, "A", "A", "A", "B", "B", "B"), X4 = c("B", "B", "A", NA, 
NA, "B", "A", NA, NA, "A", NA, NA, "A", "A", NA, NA, NA, "A", 
"B", "B", NA, "A", "B", "B", "A", "B", "B", "A", "A", NA, NA, 
NA, "A", NA, NA, NA, "A", NA, NA, "A", NA, NA, "A", "A", "B", 
"B", "B", "A", "B", "B", "B", "A", "B", "B", "A", "B", "B", "A", 
"A", NA, "B", "B", "A", NA, NA, "B", "A", NA, NA, "A", NA, NA, 
"A", "A", "B", NA, NA, "A", "B", "B", NA, "A", "B", "B", "A", 
"B", "B", "A", "A", "B"), X5 = c(NA, NA, NA, "A", NA, NA, NA, 
"A", NA, NA, "A", NA, "A", NA, "A", "B", "B", "B", "A", NA, "B", 
"B", "A", NA, "B", "A", NA, "A", NA, "A", NA, NA, NA, "A", "B", 
NA, NA, "A", "B", NA, "A", "B", "A", "B", "A", "B", "B", "B", 
"A", NA, "B", "B", "A", NA, "B", "A", NA, "A", NA, "A", NA, NA, 
NA, "A", "B", NA, NA, "A", "B", NA, "A", "B", "A", "B", "A", 
"B", "B", "B", "A", "B", "B", "B", "A", "B", "B", "A", "B", "A", 
"B", "A"), X6 = c(NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, NA, 
"A", NA, "A", "A", NA, NA, NA, NA, "A", NA, NA, NA, "A", NA, 
NA, "A", NA, "A", "A", "B", "B", "B", "B", "A", "B", "B", "B", 
"A", "B", "B", "A", "B", "A", "A", NA, NA, NA, NA, "A", NA, NA, 
NA, "A", NA, NA, "A", NA, "A", "A", "B", "B", "B", "B", "A", 
"B", "B", "B", "A", "B", "B", "A", "B", "A", "A", "B", "B", "B", 
"B", "A", "B", "B", "B", "A", "B", "B", "A", "B", "A", "A")), .Names = c("X1", 
"X2", "X3", "X4", "X5", "X6"), row.names = c(NA, -90L), class = "data.frame")

res我不认为它比for-loop解决方案好多少,但这里有一个可能的选择:

# Base R solution: 
# note that res is a data.frame of characters but 
# returned value will be a matrix of characters
toBind <- 
lapply(1:nrow(tmpCombs),function(idx){
  rowIdxs<- ((idx-1)*15+1):(idx*15)
  replaceIdxs <- tmpCombs[idx,]
  tmp <- apply(res[rowIdxs,],1,function(row){
    row[na.omit(which(is.na(row))[replaceIdxs])] <- 'B'
    return(row)
  })
  return(t(tmp))
})

fixed <- do.call(rbind,toBind)
#基本R解决方案:
#请注意,res是字符的data.frame,但
#返回值将是一个字符矩阵

toBind我不认为它比for-loop解决方案好多少,但这里有一个可能的选择:

# Base R solution: 
# note that res is a data.frame of characters but 
# returned value will be a matrix of characters
toBind <- 
lapply(1:nrow(tmpCombs),function(idx){
  rowIdxs<- ((idx-1)*15+1):(idx*15)
  replaceIdxs <- tmpCombs[idx,]
  tmp <- apply(res[rowIdxs,],1,function(row){
    row[na.omit(which(is.na(row))[replaceIdxs])] <- 'B'
    return(row)
  })
  return(t(tmp))
})

fixed <- do.call(rbind,toBind)
#基本R解决方案:
#请注意,res是字符的data.frame,但
#返回值将是一个字符矩阵

toBind
tmpcomb
可以展开以获得每行的映射:

tc2 = tmpCombs[rep(seq_len(nrow(tmpCombs)), 
                   each = nrow(res) %/% nrow(tmpCombs)), ]
dim(tc2)
#[1] 90  2
然后,仅在列上循环并计数
NA
s的连续出现,当出现特定的(根据
tmpCombs
)增加的
NA
数量时更换:

NAcounts = integer(nrow(res))
for(j in seq_along(res)) {
   nas = is.na(res[[j]])

   NAcounts = NAcounts + nas  #`NA`s found so far in each row

   #only for rows with `NA`s 
   #(no need for extended lookup if few rows contain `NA`)
   #check if _this_ appearance of `NA` matches in `tmpCombs`
   wnas = which(nas)
   matches = NAcounts[wnas] == tc2[wnas, ]

   res[[j]][wnas[as.logical(rowSums(matches))]] = "B"
}
identical(res, res2)
#[1] TRUE

tmpcomb
可以展开以获得每行的映射:

tc2 = tmpCombs[rep(seq_len(nrow(tmpCombs)), 
                   each = nrow(res) %/% nrow(tmpCombs)), ]
dim(tc2)
#[1] 90  2
然后,仅在列上循环并计数
NA
s的连续出现,当出现特定的(根据
tmpCombs
)增加的
NA
数量时更换:

NAcounts = integer(nrow(res))
for(j in seq_along(res)) {
   nas = is.na(res[[j]])

   NAcounts = NAcounts + nas  #`NA`s found so far in each row

   #only for rows with `NA`s 
   #(no need for extended lookup if few rows contain `NA`)
   #check if _this_ appearance of `NA` matches in `tmpCombs`
   wnas = which(nas)
   matches = NAcounts[wnas] == tc2[wnas, ]

   res[[j]][wnas[as.logical(rowSums(matches))]] = "B"
}
identical(res, res2)
#[1] TRUE

非常感谢。你能建议一个通用的方法,允许tmpcomb有任意数量的列吗?@GeorgeDontas:做了一些编辑;我认为
as.logical(rowSums(x==y))
(logical->numeric->logical)可能比在
x==y
的列上累积
|
的工作量要多,但是,我想,这应该不会太低效。我将res转换成了一个矩阵——这样代码运行得更快。然后我对您的代码进行了一些必要的更改,并获得了更快的执行速度。恭喜你@乔治顿塔斯:我认为使用“矩阵”可能会减慢速度,因为一般来说,
data.frame[[j]]
不会复制,而
matrix[,j]
会复制,而且,在上面的设置中,似乎没有任何“data.frame”方法的开销。还是我在你的评论中遗漏了什么?更多细节请查看该帖子,谢谢。你能建议一个通用的方法,允许tmpcomb有任意数量的列吗?@GeorgeDontas:做了一些编辑;我认为
as.logical(rowSums(x==y))
(logical->numeric->logical)可能比在
x==y
的列上累积
|
的工作量要多,但是,我想,这应该不会太低效。我将res转换成了一个矩阵——这样代码运行得更快。然后我对您的代码进行了一些必要的更改,并获得了更快的执行速度。恭喜你@乔治顿塔斯:我认为使用“矩阵”可能会减慢速度,因为一般来说,
data.frame[[j]]
不会复制,而
matrix[,j]
会复制,而且,在上面的设置中,似乎没有任何“data.frame”方法的开销。或者我在你的评论中遗漏了什么?更多细节请查看该帖子