Reputation: 647
I have a function which should update some values from a dataframe. The function gets the rowindex of the data to be changed, the dataframe as well as the variables. This function is called by sapply for all the indices to be changed. I would expect a matrix as the return of sapply and i would expect to be able to change my base dataframe by indexing. Unfortunately i cant provide real data, but the following dummy-data replicates the problem. I do not understand why it is not working. Maybe the reason is that, the matrix returned by sapply is not a "normal" matrix of integers but some sort of matrix of lists?
Dummy-Dataframe:
data_test = data.frame(matrix(1:100, 10, 10))
names(data_test) = paste0("Var", 1:10)
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
# 1 1 11 21 31 41 51 61 71 81 91
# 2 2 12 22 32 42 52 62 72 82 92
# 3 3 13 23 33 43 53 63 73 83 93
# 4 4 14 24 34 44 54 64 74 84 94
# 5 5 15 25 35 45 55 65 75 85 95
# 6 6 16 26 36 46 56 66 76 86 96
# 7 7 17 27 37 47 57 67 77 87 97
# 8 8 18 28 38 48 58 68 78 88 98
# 9 9 19 29 39 49 59 69 79 89 99
# 10 10 20 30 40 50 60 70 80 90 100
"normal" matrix to replace some of the values of data_test by indices:
data_replace = matrix(1:16, 4,4)
# [,1] [,2] [,3] [,4]
# [1,] 1 5 9 13
# [2,] 2 6 10 14
# [3,] 3 7 11 15
# [4,] 4 8 12 16
This works nice:
data_test[c("Var3", "Var4", "Var5", "Var6")][4:7,] = data_replace
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
# 1 1 11 21 31 41 51 61 71 81 91
# 2 2 12 22 32 42 52 62 72 82 92
# 3 3 13 23 33 43 53 63 73 83 93
# 4 4 14 1 5 9 13 64 74 84 94
# 5 5 15 2 6 10 14 65 75 85 95
# 6 6 16 3 7 11 15 66 76 86 96
# 7 7 17 4 8 12 16 67 77 87 97
# 8 8 18 28 38 48 58 68 78 88 98
# 9 9 19 29 39 49 59 69 79 89 99
# 10 10 20 30 40 50 60 70 80 90 100
Dummy-function to be called by sapply:
# just a test-function to be called by sapply. It multiplies all the temp_vars from temp_data in rows temp_index by 2
function_test = function(temp_index, temp_data = data_test, temp_vars = c("Var3", "Var4", "Var5", "Var6"))
{
return(temp_data[temp_vars][temp_index,] * 2)
}
Function call using sapply on some row-indices
#function call
temp_results = t(sapply(4:7, function_test))
data_test[c("Var3", "Var4", "Var5", "Var6")][4:7,]
# Var3 Var4 Var5 Var6
# 4 1 5 9 13
# 5 2 6 10 14
# 6 3 7 11 15
# 7 4 8 12 16
Trying to replace some values of data_test using indexing (just like before) does not work here unfortunately. It gives me the following error:
data_test[c("Var3", "Var4", "Var5", "Var6")][4:7,] = temp_results
# Warning message:
# In `[<-.data.frame`(`*tmp*`, 4:7, , value = list(Var3 = c(21, 22, :
# provided 16 variables to replace 4 variables
Some information about the used data. They should be all of the same size.
dim(data_test[c("Var3", "Var4", "Var5", "Var6")][4:7,])
# 4 4
dim(temp_results)
# 4 4
dim(data_replace)
# 4 4
class(temp_results)
# matrix
class(data_replace)
# matrix
This is strange for me. I dont understand what that means.
apply(temp_results, 2, class)
# Var3 Var4 Var5 Var6
# "list" "list" "list" "list"
apply(data_replace, 2, class)
# "integer" "integer" "integer" "integer"
I can work around the problem by using temp_results = lapply
instead of temp_results = sapply
and afterwards use the matrix(unlist(temp_results), 4, byrow = T)
function, but still i'd like to understand what is going on here with the return of sapply.
Any input would be great! Thanks in advance
Upvotes: 1
Views: 84
Reputation: 330
Make your function return the values as a matrix:
function_test <- function(temp_index, temp_data = data_test, temp_vars = c("Var3", "Var4", "Var5", "Var6"))
{
return(as.matrix(temp_data[temp_vars][temp_index,] * 2))
}
It should be work the way as you wish.
Upvotes: 1