My question is how to use "apply" function to do what "for loop" does in this example:
mtcars
for (i in colnames(mtcars)){
print(head(mtcars[i]))
}
What I need is to get R to read one column after the other, ideally by index (ie mtcars[1], then mtcars[2], then mtcars[3]...) rather than colnames.
Your help is highly appreciated.
Thanks
Use the apply function
apply(mtcars, 2 ,head)
this is the result
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
Explanation
2 in the parameter of apply function means you're going to pass each column to your defined function , if you pass 1 instead of 2 this means that you're going to send each row instead of column
Related
When I run colnames(), it never shows the name of this first column.
For example, after wasting a lot of time researching online, I discovered the name of the first column in mtcars is das_Auto.
Why doesn't this name show when I run this code?
[colnames(mtcars)][1]
What's the easiest way to determine the name of the first column in a data set?
This is because the first 'column' of mtcars is not actually a column but an index. If you want to convert it to a column you can run the below:
df <- cbind(das_Auto = rownames(mtcars), mtcars)
rownames(df) <- 1:nrow(mtcars)
head(df)
das_Auto mpg cyl disp hp drat wt qsec vs am gear carb
1 Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
2 Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
3 Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
4 Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
5 Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
6 Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
I am just trying to fill gaps but in a loop. It is a monthly data, and fill_gaps produces NAs for every day. I am not sure why.
for (x in 2:length(differencing)){
for(micky in 1:length(differencing$`d_ BA`)){
if(is.na(differencing[micky,x])== T){
differencing[micky,x] = differencing[micky-1,x]
}
}
}
here is the error that I am getting:
Error: Assigned data `differencing[(micky - 1), x]` must be compatible with row subscript `micky`.
x 1 row must be assigned.
x Assigned data has 0 rows.
i Row updates require a list value. Do you need `list()` or `as.list()`?
Run `rlang::last_error()` to see where the error occurred.
This can be easily done using fill
library(tidyr)
library(dplyr)
differencing %>%
fill(everything())
Or we can use na.locf from zoo
library(zoo)
na.locf(differencing)
In the OP's loop, in the first line, it would be
for (x in 2:length(differencing$`d_ BA`)
...
as length of a data.frame will be the number of columns (as mentioned in the comments) and is different from length of a column i.e. vector
As the OP mentioned none of them works (OP didn't provide any example), using a small reproducible example ('tmp')
tmp %>%
fill(everything())
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 18.7 6 258 110 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 6 258 110 2.76 3.460 20.22 1 0 3 1
or using na.locf
na.locf(tmp)
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 18.7 6 258 110 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 6 258 110 2.76 3.460 20.22 1 0 3 1
data
tmp <- head(mtcars)
tmp[c(2, 5, 6), c(3, 4, 2)] <- NA
I am trying to convert my list consisting of 52 components to a dataframe for each of the components.
Without using the for loop will look something like this which is tedious:
df1 = as.data.frame(list[1])
df2 = as.data.frame(list[2])
df3 = as.data.frame(list[3])
.
.
.
df50 = as.data.frame(list[50])
How do I achieve this using the for loop? My attempt:
for (i in seq_along(list)) {
noquote(paste0("df", i)) = as.data.frame(list[i])
}
Error: target of assignment expands to non-language objec
I think I'll have to invovle assign.
If you have list of dataframes in list, you can name them and then use list2env to have them as separate dataframes in the environment.
names(list) <- paste0('df', seq_along(list))
list2env(list, .GlobalEnv)
Using a reproducible exmaple,
temp <- list(mtcars, mtcars)
names(temp) <- paste0('df', seq_along(temp))
list2env(temp, .GlobalEnv)
head(df1)
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
head(df2)
# mpg cyl disp hp drat wt qsec vs am gear carb
#Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
#Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
#Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
#Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
#Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
#Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
However, note that
list is an internal function in R, so it is better to name your variables something else.
As #MrFlick suggested try to keep your data in a list as lists are easier to manage rather than creating numerous objects in your global environment.
We can use assign instead of noquote from the OP's function
for (i in seq_along(list)) {
assign(paste0("df", i), value = list[[i]])
}
I would like to define a string
string<- "modelName"
That could be used to name an object later. Something like
paste0(string) <- mtcars
cat(string) <- mtcars
print(string) <- mtcars
get(string) <- mtcars
The needed result is the dataset called "modelName". None of the examples above work, obviously.
Question:
How can create one create an object which name is defined by the sourced string?
As #Spacedman notes this is not generally the way things are done but you can use assign
string<- "modelName"
assign(string, mtcars)
> head(modelName)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
In general it may be perferable to use sometthing like a list:
x <- list()
x[[string]] <- mtcars
> head(x$modelName)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
I pass data frame name as string into a function. How do I get content of referenced data frame from the string? Suppose I have string 'mtcars' and I want to print data frame mtcars:
printdf <- function(dataframe) {
print(dataframe)
}
printdf('mtcars');
I think you'll need a get in there if the input is a string. Also, depending on your usage of the function, the explicit print might not be necessary:
printdf <- function(dataframe) {
get(dataframe)
# print(get(dataframe))
}
head(printdf("mtcars"))
# mpg cyl disp hp drat wt qsec vs am gear carb
# Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
# Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
# Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
# Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
# Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
# Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1