cbind() function works as x <- cbind(a,b)
where column name 'b' can be specified for the function b = get(paste0('var',i)),
that is x <- cbind(a,b = get(paste0('var',i)))
I am trying to do the following:
x <- cbind(a, get(paste0('var',i))) = j), where "j" can be a vector or a function.
however, got the following error: Error: unexpected '=' in "x <- cbind(a, get(paste0('var',i))) = j)"
If i just specify "x <- cbind(a, get(paste0('var',i))))", then the 2nd column name is "get(paste0('var',i))))", which is not convenient.
How can I define column names with a function get(paste()) within cbind() or rbind() or bind_cols()? Or what would be the alternative solution?
An example would have been helpful to understand the problem but maybe this?
x <- cbind(a, j)
colnames(x)[2] <- get(paste0('var',i))
Or if you want to do it in single line -
x <- cbind(a, setNames(j, get(paste0('var',i))))
We can use
x <- data.frame(a, j)
colnames(x)[2] <- get(paste('var', i, sep=""))
Or use tibble
tibble(a, !! b := j)
Related
I have a function that I want to apply to a dataset, but the function also uses global variables as arguments as these variables are needed elsewhere.
With this reduced example I want to apply 'pterotest' to the rows of 'data'. This test case works when the function is given V as a vector, and M and g as a single value.
df<- data.frame(matrix(ncol = 1, nrow = 3))
row.names(df) <- c("Apsaravis_ukhaana", "Jeholornis_prima", "Changchengornis_hengdaoziensis")
colnames(df) <- "M"
mass_var <- c(0.1840000, 1.6910946, 0.0858997)
df$M <- mass_var
V <- seq(0.25,30, by = 0.05)
g <- 9.81
pterotest <- function(V, M, g) {
out1 <- M*g
out2 <- V*M
return(list(V, out1, out2))
}
apply(df,1,pterotest, M = "M", g = g, V = V)
However, all I get is an error of the form:
Error in match.fun(FUN) : '1' is not a function, character or symbol
EDIT: Turning this on it's head, what I could do would be to run a loop over each row, using the multiple columns as different arguments to the function, but with a 4.2M line dataset I feel vectorising might be quicker...
Hello I have a vector such as
x<-c(**131144**,**1311605**,1311766,1312289,1312804) in R
And then another data frame like:
v1 , v2
**131144,1283758**
**1283758,19527672**
**1311605,19950311**
198151,37268685
**19950311,35307140**
11281862,11292508
35261079,26296073
625349,37306860
84255273,84259752
I would like to end up with a final vector like this one
x<-c(**19527672**,**19950311**,1311766,1312289,1312804)
Is like to iteratively searching for a value and when a match is found updating it and then keep searching for the updated value until no match found.
Thks in advance.
An option with igraph
g <- graph_from_data_frame(df)
v <- membership(components(g))
tb <- by(names(v), v, function(x) x[degree(g, x, mode = "out") == 0])
m <- unname(v[as.character(x)])
ifelse(is.na(m), x, as.numeric(tb[m]))
gives
[1] 19527672 35307140 1311766 1312289 1312804
where plot(g) shows
Alittle tweak to the solution found here and we have the following:
relation <- function(vec, dat){
.relation <- function(x){
k = unique(c(dat[dat[, 1] %in% x, 2], x, dat[dat[, 2] %in% x, 1]))
if(setequal(x,k)) tail(k, 2)[1] else Recall(k)
}
y <- unique(vec)
sapply(y, .relation)[match(vec, y)]
}
relation(x, df)
[1] 19527672 35307140 1311766 1312289 1312804
I have a data frame:
df <- data.frame( a = 1:5, b = 1:5, c = 1:5, d = as.factor(1:5))
I want to write a function that takes as its argument one of the columns a,b or c, and one of the factors of column d, and returns only the values of column a, b, or c, that have said factor value for column d.
I tried the following code:
fun1 <- function(x,y) {
u <- x[data$d == "y"]
return(u)
}
and I keep getting back numeric(0) as the output of the function. When I try similar code outside of the function() environment, it appears to work fine. Any help would be appreciated.
Probably a duplicate but I don't know how I would find it in the haystack of items with tags: data.frame, indexing, columns, values. Best practice is to pass the "data" as well as the search terms. (Calling the object df1 rather than df.)
fun1 <- function(dfrm, col,val) {
u <- dfrm[dfrm$d == val , col]
return(u)
}
fun1(df1, 'b', 3)
#[1] 3
Given three rasters, I need to extract values corresponding to u (row) = 5 and c (column) from a text file smoke.
smoke <- matrix(c(5, 4, 2, 9, 2, 2), ncol=2, byrow=TRUE)
The function I'm using is:
library(raster)
r <- raster(nrows=10, ncols=10)
r <- setValues(r, 1:ncell(r))
func <- function(c, u, sit){
rasters <- mget(c('r', paste0('r', 1:2)))
x <- sapply(rasters, function(x) getValues(x, c)[u])
y <- sapply(rasters, function(x) getValues(x, u)[c])
g <- data.frame(y, x)
write.table(g, paste0("res_", sit, u, "_", c, ".txt"))
}
Here's how I use the function to extract values that correspond to c and u in smoke:
res <- lapply(split(smoke[,c('c', 'u', 'sit')], 1:nrow(smoke)),
FUN=function(x) func(c=x[1], u=x[2], sit=x[3]))
I get this error: error: value for ‘r’ not found
By default, mget only looks for the objects r, r1, and r2 in the environment in which it's called, but in your case, those objects are in the global environment. You can either add inherits=TRUE to the mget call, which will force it to keep looking in parent environments, or else specify the environment to look in with envir=.GlobalEnv.
You have a couple of other problems, though.
First, r1 and r2 don't exist in your example.
Second, the list arising from split is a list of data frames, and you need to index them accordingly in your function. This means either using $ notation (e.g. x$c), double brackets (e.g. x[[1]]), or use a comma (e.g. x[, 1]).
Implementing all of this, you should have something like:
func <- function(c, u, sit) {
rasters <- mget(c('r', paste0('r', 1:2)), envir=.GlobalEnv)
x <- sapply(rasters, function(x) getValues(x, c)[u])
y <- sapply(rasters, function(x) getValues(x, u)[c])
g <- data.frame(y, x)
write.table(g, paste0("res_", sit, u, "_", c, ".txt"))
}
library(raster)
res <- lapply(split(smoke[, c('c', 'u', 'sit')], 1:nrow(smoke)),
function(x) func(c=x[[1]], u=x[[2]], sit=x[[3]]))
Finally, res will just be a list of NULL values, since your function returns the value of write.table, which is NULL. If you want func to return g, then add a final line to the function that simply reads g (or, explicitly, return(g)).
I'm not sure how closely your small example reflects your true data, but you could probably approach this more efficiently - see ?extract, ?cellFromRowCol, and ?stack, for example.
Please note that I already had a look at this and that but still cannot solve my problem.
Suppose a minimal working example:
a <- c(1,2,3)
b <- c(2,3,4)
c <- c(4,5,6)
dftest <- data.frame(a,b,c)
foo <- function(x, y, data = data) {
data[, c("x","y")]
}
foo(a, b, data = dftest)
Here, the last line obviously returns an Error: undefined columns selected. This error is returned because the columns to be selected are x and y, which are not part of the data frame dftest.
Question: How do I need to formulate the definition of the function to obtain the desired output, which is
> dftest[, c("a","b")]
# a b
# 1 1 2
# 2 2 3
# 3 3 4
which I want to obtain by calling the function foo.
Please be aware that in order for the solution to be useful for my purposes, the format of the function call of foo is to be regarded fixed, that is, the only changes are to be made to the function itself, not the call. I.e. foo(a, b, data = dftest) is the only input to be allowed.
Approach: I tried to use paste and substitute in combination with eval to first replace the x and y with the arguments of the function call and then evaluate the call. However, escaping the quotation marks seems to be a problem here:
foo <- function(x, y, data = data) {
substitute(data[, paste("c(\"",x,"\",\"",y,"\")", sep = "")])
}
foo(a, b, data = dftest)
eval(foo(a, b, data = dftest))
Here, foo(a, b, data = dftest) returns:
dftest[, paste("c(\"", a, "\",\"", b, "\")", sep = "")]
However, when evaluating with eval() (focusing only on the paste part),
paste("c(\"", a, "\",\"", b, "\")", sep = "")
returns:
# "c(\"1\",\"2\")" "c(\"2\",\"3\")" "c(\"3\",\"4\")"
and not, as I would hope c("a","b"), thus again resulting in the same error as above.
Try this:
foo <- function(x, y, data = data) {
x <- deparse(substitute(x))
y <- deparse(substitute(y))
data[, c(x, y)]
}