Creating and appending to data frame in R (Error: arguments imply differing number of rows: 0, 1)

StackOverflow https://stackoverflow.com/questions/23537586

  •  17-07-2023
  •  | 
  •  

Question

I am creating and appending to a data frame in R:

dat <- data.frame(nodeA = character(), nodeB = character(), edge = numeric())
for (i in 1:length(countTable)-1){
  for (j in i+1:length(countTable)){
    vecA = as.numeric(as.character(countTable[i,]))
    vecB = as.numeric(as.character(countTable[j,]))
    nodeA = row.names(countTable[i,])
    nodeB = row.names(countTable[j,])
    corCoeff = cor(vecA , vecB , method = "spearman")
    dat = rbind(dat, data.frame(nodeA = nodeA, nodeB = nodeB, edge = corCoeff))
  }
}

Where a head and structure of the countTable are as follows:

> head(countTable)
                Norm One Two Three Four
ENST00000000233   12  28  11     4    8
ENST00000000412   23  44  37    23   45
ENST00000000442    9  12  27    10   22
ENST00000001008   18  98  61    21   31
ENST00000001567   16   7   3     9   12
ENST00000002125    2   4   4     5    1

> str(countTable)
'data.frame':   17972 obs. of  5 variables:
 $ Norm : int  12 23 9 18 16 2 4 1 22 14 ...
 $ One  : int  28 44 12 98 7 4 24 14 39 39 ...
 $ Two  : int  11 37 27 61 3 4 12 3 69 30 ...
 $ Three: int  4 23 10 21 9 5 4 3 271 9 ...
 $ Four : int  8 45 22 31 12 1 13 7 123 60 ...

If I look at the code in the nested for loop individually, it works as I hope for. However, when I run the entire code, I get an error:

Error in data.frame(nodeA = nodeA, nodeB = nodeB, edge = corCoeff) : 
  arguments imply differing number of rows: 0, 1
In addition: Warning message:
NAs introduced by coercion 
Was it helpful?

Solution 2

You may want something like this. Convert countTable to a matrix and drop down to one loop, using i and i-1 for the loop indices. And there is no need to create an empty data frame beforehand.

> countTable <- as.matrix(countTable)
> rn <- rownames(countTable)
> dat <- do.call(rbind, lapply(2:nrow(countTable), function(i){
    corCoeff <- cor(countTable[i-1,] , countTable[i,], 
                    method = "spearman", use = "complete.obs")
    data.frame(nodeA = rn[i-1], nodeB = rn[i], edge = corCoeff)
    }))
> dat
#             nodeA           nodeB       edge
# 1 ENST00000000233 ENST00000000412  0.1538968
# 2 ENST00000000412 ENST00000000442  0.6668859
# 3 ENST00000000442 ENST00000001008  0.7000000
# 4 ENST00000001008 ENST00000001567 -0.8000000
# 5 ENST00000001567 ENST00000002125 -0.5642881

OTHER TIPS

The : operator has higher precedence than + and -. Your code should be corrected to:

for (i in 1:(length(countTable)-1)){
   for (j in (i+1):length(countTable)){
      ...
   }
}

Note the difference between:

n <- 3
for (i in 1:n-1)
  for (j in i+1:n)
    cat(sprintf("(%g,%g)\n", i, j))
## (0,1)
## (0,2)
## (0,3)
## (1,2)
## (1,3)
## (1,4)
## (2,3)
## (2,4)
## (2,5)

and:

for (i in 1:(n-1))
  for (j in (i+1):n)
    cat(sprintf("(%g,%g)\n", i, j))
## (1,2)
## (1,3)
## (2,3)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top