Inserting the value in data frame into the codes in R - r

I have the names of the 1000 people in "name" data frame
df=c("John","Smith", .... "Machine")
I have the 1000 data frames for each person. (e.g., a1~a1000)
And, I have the following codes.
a1$name="XXXX"
a2$name="XXXX" ...
a1000$name="XXXX"
I would like to replace "XXXX" in the above codes with the values in name data frame. Output codes would look like this.
a1$name="John"
a2$name="Smith" ...
a1000$name="Machine"

First you need to combine them as List.( I do not know whether it is work with 1000 dataframe or not. )
df=c("John","Smith", .... "Machine")
list_object_names = sprintf("a%s", 1:1000)
list_df = lapply(list_object_names, get)
for (i in 1:length(list_df) ){
list_df[[i]][,'Names']=df[i]
}
Also you can try apply function rather than for loop something like:
lapply(list_df, function(df) {
#what you want to do
})

Here is my shot at this, without knowing if there is any more to the a1,a2...a1000 lists.
# generate your data
df = c("John", "Smith", "Machine")
# build your example
for(i in 1:3){
assign(paste0("a",i), list(name = "XXXX"))
}
# solve your problem, even if there is more to a1 than you are showing us.
for(i in 1:3){
anew <- get(paste0("a",i)) # pulls the object form the environment
anew[['name']] <- df[i] # rewrites only that list
assign(paste0("a",i), anew) # rewrites the object with new name
}

Related

Nested lappy in r

So I have function that takes 2 argument to read txt files from a site. The arguments are 1 the names of city and the 2nd one is the type of data. I have 2 list to pass it down as arguments which are the list of cities and the list of type of data. How could i use nested lapply to read the files from the site?My attempt of the code look something like this:
cities <- c("sydney","brisbane"...)
typedatas <- c("Max", "Avg","Min")
url<- "https:/sitename/datasets/"
read.text <- function(city, typedata){
c(url,typedata,"/year/",city, ".txt) >%>
paste0()
}
finaldata <- lapply(cities, function(x) lapply(typedatas,function(x){read.ts})) %>% set_names(cities)
it creates a big list but the did not completely read the files. The output would be like below:
final data list [10]
sydney list[3]
function
function
function
brisbane list[3]
function...
....
how can i make it read and also appropriately name the dataframes using the type of data for each cities.
Kind of hard to do this without a reproducible example but you can try this:
cities <- c("sydney","brisbane")
typedatas <- c("Max", "Avg","Min")
url<- "https:/sitename/datasets/"
read.text <- function(city, typedata){
paste0(url,typedata,"/year/",city, ".txt")
}
finaldata <- lapply(cities, function(cty){
lapply(typedatas,function(ds_type){
read.text(cty, ds_type)
})
}) %>% set_names(cities)
Notice that your read.text function doesn't actually read the file but only creates the hyperlink to it so you will need to add some kind of function to actually read the file.

R function used to rename columns of a data frames

I have a data frame, say acs10. I need to relabel the columns. To do so, I created another data frame, named as labelName with two columns: The first column contains the old column names, and the second column contains names I want to use, like the table below:
column_1
column_2
oldLabel1
newLabel1
oldLabel2
newLabel2
Then, I wrote a for loop to change the column names:
for (i in seq_len(nrow(labelName))){
names(acs10)[names(acs10) == labelName[i,1]] <- labelName[i,2]}
, and it works.
However, when I tried to put the for loop into a function, because I need to rename column names for other data frames as well, the function failed. The function I wrote looks like below:
renameDF <- function(dataF,varName){
for (i in seq_len(nrow(varName))){
names(dataF)[names(dataF) == varName[i,1]] <- varName[i,2]
print(varName[i,1])
print(varName[i,2])
print(names(dataF))
}
}
renameDF(acs10, labelName)
where dataF is the data frame whose names I need to change, and varName is another data frame where old variable names and new variable names are paired. I used print(names(dataF)) to debug, and the print out suggests that the function works. However, the calling the function does not actually change the column names. I suspect it has something to do with the scope, but I want to know how to make it works.
In your function you need to return the changed dataframe.
renameDF <- function(dataF,varName){
for (i in seq_len(nrow(varName))){
names(dataF)[names(dataF) == varName[i,1]] <- varName[i,2]
}
return(dataF)
}
You can also simplify this and avoid for loop by using match :
renameDF <- function(dataF,varName){
names(dataF) <- varName[[2]][match(names(dataF), varName[[1]])]
return(dataF)
}
This should do the whole thing in one line.
colnames(acs10)[colnames(acs10) %in% labelName$column_1] <- labelName$column_2[match(colnames(acs10)[colnames(acs10) %in% labelName$column_1], labelName$column_1)]
This will work if the column name isn't in the data dictionary, but it's a bit more convoluted:
library(tibble)
df <- tribble(~column_1,~column_2,
"oldLabel1", "newLabel1",
"oldLabel2", "newLabel2")
d <- tibble(oldLabel1 = NA, oldLabel2 = NA, oldLabel3 = NA)
fun <- function(dat, dict) {
names(dat) <- sapply(names(dat), function(x) ifelse(x %in% dict$column_1, dict[dict$column_1 == x,]$column_2, x))
dat
}
fun(d, df)
You can create a function containing just on line of code.
renameDF <- function(df, varName){
setNames(df,varName[[2]][pmatch(names(df),varName[[1]])])
}

Parsing colnames text string as expression in R

I am trying to create a large number of data frames in a for loop using the "assign" function in R. I want to use the colnames function to set the column names in the data frame. The code I am trying to emulate is the following:
county_tmax_min_df <- data.frame(array(NA,c(length(days),67)))
colnames(county_tmax_min_df) <- c('Date',sd_counties$NAME)
county_tmax_min_df$Date <- days
The code I have so far in the loop looks like this:
file_vars = c('file1','file2')
days <- seq(as.Date("1979-01-01"), as.Date("1979-01-02"), "days")
f = 1
for (f in 1:2){
assign(paste0('county_',file_vars[f]),data.frame(array(NA,c(length(days),67))))
}
I need to be able to set the column names similar to how I did in the above statement. How do I do this? I think it needs to be something like this, but I am unsure what goes in the text portion. The end result I need is just a bunch of data frames. Any help would be wonderful. Thank you.
expression(parse(text = ))
You can set the names within assign, like that:
file_vars = c('file1', 'file2')
days <- seq.Date(from = as.Date("1979-01-01"), to = as.Date("1979-01-02"), by = "days")
for (f in seq_along(file_vars)) {
assign(x = paste0('county_', file_vars[f]),
value = {
df <- data.frame(array(NA, c(length(days), 67)))
colnames(df) <- paste0("fancy_column_",
sample(LETTERS, size = ncol(df), replace = TRUE))
df
})
}
When in {} you can use colnames(df) or setNames to assign column names in any manner desired. In your first piece of code you are referring to sd_counties object that is not available but the generic idea should work for you.

R: How can I append multiple rows to a data.frame during a loop?

I discovered that it seems that I can not add rows to a data.frame in place.
The following code is a minimal example which should append a new row to the data.frame every iteration, but it does not append any.
Please note, in reality I have a complex for-loop with a lot of different if-statements and depending on them I want to append new different data to different data frames.
df <- data.frame(value=numeric())
appendRows <- function(n_rows) {
for(i in 1:n_rows) {
print(i)
df <- rbind(df, setNames(i,names(df)))
}
}
appendRows(10) #Does not append any row, whereas "df <- rbind(df, setNames(1,names(df)))" in a single call appends one row.
How can rows be added to a data.frame in place?
Thanks :-)
Don't forget to return your object:
df <- data.frame(value=numeric())
appendRows <- function(n_rows) {
for(i in 1:n_rows) {
print(i)
df <- rbind(df, setNames(i,names(df)))
}
return(df)
}
appendRows(10)
To modify df you have to store it:
df <- appendRows(10)

r - create matrix from data frame loop

I have many data frames id.1, id.2, ... ,id.21 and in each of which I want to extract 2 data points: id.1[5,4] and id.1[10,6], id.2[5,4] and id.2[10,6], etc. The first data point is a date and the second data point is a integer.
I want to export this list to obtain something like this in an .csv file:
V1 V2
1 5/10/2016 1654395291
2 5/11/2016 1645024703
3 5/12/2016 1763825219
I have tried
x=c(for (i in 1:21) {
file1 = paste("id.", i, "[5,4]", sep="")}, for (i in 1:21) {
file1 = paste("id.", i, "[10,6]", sep="")})
write.csv(x, "x.csv")
But this yields x being NULL. How can I go about getting this vector?
Your problem is that a for loop doesn't return anything in R. So you can't use it in a c statement as you did. Use an [sl]apply construct instead.
I would first make a list containing all the data frames:
dfs <- list(id.1, id.2, id.3, ...)
And iterate over it, something like:
x <- sapply(dfs, function(df) {
return(c(df[5,4], df[10,6]))
})
Finally you need to transpose the result and convert it into a data.frame if you want to:
x <- as.data.frame(t(x))

Resources