> Consider a data.frame whose different columns have numeric, character, > and factor data. In apply function, R seems to pass all elements of a > row as character. Is it possible to preserve numeric class? > >> mydf <- data.frame(x = rnorm(10), y = runif(10)) >> apply(mydf, 1, function(row) {row["x"] + row["y"]}) > [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 0.31351909 > [7] -0.63575990 0.22670658 0.55696314 0.39587314 >> mydf[, "z"] <- sample(letters[1:3], 10, replace = TRUE) >> apply(mydf, 1, function(row) {row["x"] + row["y"]}) > Error in row["x"] + row["y"] (from #1) : non-numeric argument to binary operator >> apply(mydf, 1, function(row) {as.numeric(row["x"]) + as.numeric(row["y"])}) > [1] 0.60150194 -0.74201826 0.80476394 -0.59729282 -0.02980338 0.31351912 > [7] -0.63575991 0.22670663 0.55696309 0.39587311 >> apply(mydf[,c("x", "y")], 1, function(row) {row["x"] + row["y"]}) > [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 0.31351909 > [7] -0.63575990 0.22670658 0.55696314 0.39587314
It is not possible, apply() converts its argument to an array. You might be able to use split() and lapply() to solve your problem. On Tue, Feb 7, 2023, 07:52 Naresh Gurbuxani <naresh_gurbuxani at hotmail.com> wrote:> > > Consider a data.frame whose different columns have numeric, character, > > and factor data. In apply function, R seems to pass all elements of a > > row as character. Is it possible to preserve numeric class? > > > >> mydf <- data.frame(x = rnorm(10), y = runif(10)) > >> apply(mydf, 1, function(row) {row["x"] + row["y"]}) > > [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 > 0.31351909 > > [7] -0.63575990 0.22670658 0.55696314 0.39587314 > >> mydf[, "z"] <- sample(letters[1:3], 10, replace = TRUE) > >> apply(mydf, 1, function(row) {row["x"] + row["y"]}) > > Error in row["x"] + row["y"] (from #1) : non-numeric argument to binary > operator > >> apply(mydf, 1, function(row) {as.numeric(row["x"]) + > as.numeric(row["y"])}) > > [1] 0.60150194 -0.74201826 0.80476394 -0.59729282 -0.02980338 > 0.31351912 > > [7] -0.63575991 0.22670663 0.55696309 0.39587311 > >> apply(mydf[,c("x", "y")], 1, function(row) {row["x"] + row["y"]}) > > [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 > 0.31351909 > > [7] -0.63575990 0.22670658 0.55696314 0.39587314 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
?s 12:51 de 07/02/2023, Naresh Gurbuxani escreveu:> >> Consider a data.frame whose different columns have numeric, character, >> and factor data. In apply function, R seems to pass all elements of a >> row as character. Is it possible to preserve numeric class? >> >>> mydf <- data.frame(x = rnorm(10), y = runif(10)) >>> apply(mydf, 1, function(row) {row["x"] + row["y"]}) >> [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 0.31351909 >> [7] -0.63575990 0.22670658 0.55696314 0.39587314 >>> mydf[, "z"] <- sample(letters[1:3], 10, replace = TRUE) >>> apply(mydf, 1, function(row) {row["x"] + row["y"]}) >> Error in row["x"] + row["y"] (from #1) : non-numeric argument to binary operator >>> apply(mydf, 1, function(row) {as.numeric(row["x"]) + as.numeric(row["y"])}) >> [1] 0.60150194 -0.74201826 0.80476394 -0.59729282 -0.02980338 0.31351912 >> [7] -0.63575991 0.22670663 0.55696309 0.39587311 >>> apply(mydf[,c("x", "y")], 1, function(row) {row["x"] + row["y"]}) >> [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 0.31351909 >> [7] -0.63575990 0.22670658 0.55696314 0.39587314 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.Hello, The last form, apply(mydf[,c("x", "y")], 1, function(row) {row["x"] + row["y"]}) is the right one. If your data has columns of a mix of classes, then the rows which are vectors are coerced to the greatest common denominator class. From ?c: Details The output type is determined from the highest type of the components in the hierarchy NULL < raw < logical < integer < double < complex < character < list < expression. Also, since you have a data.frame the following is another possible way: apply(mydf[c("x", "y")], 1, function(row) {row["x"] + row["y"]}) This doesn't work with matrices. Hope this helps, Rui Barradas
Hi Naresh If you wanted to automate the function a bit you can use sapply to find numeric columns ind <- sapply(mydf, is.numeric) and use it in apply construct apply(mydf[,ind], 1, function(row) sum(row)) [1] 2.13002569 0.63305300 1.48420429 0.13523859 1.17515873 -0.98531131 [7] 0.47044467 0.23914494 0.26504430 0.02037657 Cheers Petr> -----Original Message----- > From: R-help <r-help-bounces at r-project.org> On Behalf Of Naresh Gurbuxani > Sent: Tuesday, February 7, 2023 1:52 PM > To: r-help at r-project.org > Subject: [R] preserve class in apply function > > > > Consider a data.frame whose different columns have numeric, character, > > and factor data. In apply function, R seems to pass all elements of a > > row as character. Is it possible to preserve numeric class? > > > >> mydf <- data.frame(x = rnorm(10), y = runif(10)) > >> apply(mydf, 1, function(row) {row["x"] + row["y"]}) > > [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 > 0.31351909 > > [7] -0.63575990 0.22670658 0.55696314 0.39587314 > >> mydf[, "z"] <- sample(letters[1:3], 10, replace = TRUE) > >> apply(mydf, 1, function(row) {row["x"] + row["y"]}) > > Error in row["x"] + row["y"] (from #1) : non-numeric argument to binary > operator > >> apply(mydf, 1, function(row) {as.numeric(row["x"]) + > as.numeric(row["y"])}) > > [1] 0.60150194 -0.74201826 0.80476394 -0.59729282 -0.02980338 > 0.31351912 > > [7] -0.63575991 0.22670663 0.55696309 0.39587311 > >> apply(mydf[,c("x", "y")], 1, function(row) {row["x"] + row["y"]}) > > [1] 0.60150197 -0.74201827 0.80476392 -0.59729280 -0.02980335 > 0.31351909 > > [7] -0.63575990 0.22670658 0.55696314 0.39587314 > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guidehttp://www.R-project.org/posting-guide.html> and provide commented, minimal, self-contained, reproducible code.