By assigning date_[c], I have 35 "date_c"'s(below code).
for (c in 1:nrow(datetable2)) {
assign(paste("date_",c,sep=""),dt2[which(dt2$Date==datetable2$Date[c]),])
}
Now, I want to change each "date_c"'s rownames to 1:length(date_c). I used the code below but it doesn't work. The program says it can not find "date_[d]". How should I change the "date_[d]" issue in the below loophole?
for (d in 1:nrow(datetable2)){
rownames(date_[d]) <- seq(length=nrow(date_[d]))
}
Get all the date_c daatframes in a list, use lapply to iterate over it and remove the rownames. When we remove the rownames it actually recreates the rownames from 1:nrow(data).
result <- lapply(mget(ls(pattern = 'date_')), function(x)
{rownames(x) <- NULL;x})
result would have a list of dataframes with the rownames as we want. It is better to keep data in a list as it is easier to manage them. If you still want the changes to reflect in the original dataframe you can use list2env.
list2env(result, .GlobalEnv)
Related
Very green R user here. Sorry if this is asked and answered somewhere else, I haven't been able to find anything myself.
I can't figure out why I can't get a for loop to work define multiple new dataframes but looping through a predefined list.
My list is defined from a subset of variable names from an existing dataframe:
varnames <- colnames(dplyr::select(df_response, -1:-4))
Then I want to loop through the list to create a new dataframe for each variable name on the list containing the results of summary function:
for (i in varnames){
paste0("df_",i) <- summary(paste0("df$",i))
}
I've tried variations with and without paste function but I can't get anything to work.
paste0 returns a string. Both <- and $ require names, but you can use assign and [[ instead. This should work:
varnames <- colnames(dplyr::select(df_response, -1:-4))
for (i in varnames){
assign(
paste0("df_", i),
summary(df[[i]])
)
}
Anyway, I'd suggest working with a list and accessing the summaries with $:
summaries <- df_response |>
dplyr::select(-(1:4)) |>
purrr::imap(summary)
summaries$firstvarname
I'm trying to convert these lists like Python's list. I've used these codes
library(GenomicRanges)
library(data.table)
library(Repitools)
pcs_by_tile<-lapply(as.list(1:length(tiled_chr)) , function(x){
obj<-tileSplit[[as.character(x)]]
if(is.null(obj)){
return(0)
} else {
runs<-filtered_identical_seqs.gr[obj]
df <- annoGR2DF(runs)
score = split(df[,c("start","end")], 1:nrow(df[,c("start","end")]))
#print(score)
return(score)
}
})
dt_text <- unlist(lapply(tiled_chr$score, paste, collapse=","))
writeLines(tiled_chr, paste0("x.txt"))
The following line of code iterates through each row of the DataFrame (only 2 columns) and splits them into the list. However, its output is different from what I desired.
score = split(df[,c("start","end")], 1:nrow(df[,c("start","end")]))
But I wanted the following kinda output:
[20350, 20355], [20357, 20359], [20361, 20362], ........
If I understand your question correctly, using as.tuple from the package 'sets' might help. Here's what the code might look like
library(sets)
score = split(df[,c("start","end")], 1:nrow(df[,c("start","end")]))
....
df_text = unlist(lapply(score, as.tuple),recursive = F)
This will return a list of tuples (and zeroes) that look more like what you are looking for. You can filter out the zeroes by checking the type of each element in the resulting list and removing the ones that match the type. For example, you could do something like this
df_text_trimmed <- df_text[!lapply(df_text, is.double)]
to get rid of all your zeroes
Edit: Now that I think about it, you probably don't even need to convert your dataframes to tuples if you don't want to. You just need to make sure to include the 'recursive = F' option when you unlist things to get a list of 0s and dataframes containing the numbers you want.
This is probably a very simple problem but I have been struggling to search for this issue. Basically, I am using lapply to convert the column names to upper in a list of dataframes. My first attempt did not work, however adding ;x works. What exactly is going on?
This does not work:
df.list <- lapply(df.list,function(x) colnames(x) <- toupper(colnames(x)))
This does:
df.list <- lapply(df.list,function(x) {colnames(x) <- toupper(colnames(x));x})
Since you are modifying the object x (or in this case only the colnames of x) inside the function definition, you have to return the modified object x. This is happening by using ;x which can be read as a new line only returning the object x
This topic has been covered numerous times I see but I can't really get the answer I'm looking for. Thus, here I go.
I am trying to do a loop to create variables in 5 data sets that have similar names as such:
Ech_repondants_nom_1
Ech_repondants_nom_2
Ech_repondants_nom_3
Ech_repondants_nom_4
Ech_repondants_nom_5
Below if the code that I have tried:
list <- c(1:5)
for (i in list) {
Ech_repondants_nom_[[i]]$sec = as.numeric(Ech_repondants_nom_[[i]]$interviewtime)
Ech_repondants_nom_[[i]]$min = round(Ech_repondants_nom_[[i]]$sec/60,1)
Ech_repondants_nom_[[i]]$heure = round(Ech_repondants_nom_[[i]]$min/60,1)
}
Any clues why this does not work?
cheers!
These are object names and not list elements to subset as Ech_repondants_nom_[[i]]. We may need to get the object by paste i.e.
get(paste0("Ech_repondants_nom_", i)$sec
but, then if we need to update the original object, have to call assign. Instead of all this, it can be done more easily if we load the datasets into a list and loop over the list with lapply
lst1 <- lapply(mget(paste0("Ech_repondants_nom_", 1:5)), function(dat)
within(dat, {sec <- as.numeric(interviewtime);
min <- round(sec/60, 1);
heure <- round(min/60, 1)}))
It may be better to keep it as a list, but if we need to update the original object, use list2env
list2env(lst1, .GlobalEnv)
Ech_repondants_nom_[[i]]
Isn't actually selcting that dataframe because you can't call objects like that. Try creating a function that takes a dataframe as an argument then iterating through the dataframes
changing_time_stamp<-function(df){
df$sec = as.numeric(df$interviewtime)
df$min = round(df$sec/60,1)
df$heure = round(df$min/60,1)
for (i in list) {
changing_time_stamp(i)
}
EDIT: I fixed some of the variable names in the function
I am trying to rename columns in a dataframe in R. However, the renaming has circular referencing. I would like a solution to this problem, the circular referencing cannot be avoided. One way to think was to rename a column and move it to a new dataframe, hence, avoiding the circular referencing. However, I am unable to do so.
The renaming reference is as follows:
The current function I am using is as follows:
standard_mapping <- function(mapping.col, current_name, standard_name, data){
for(i in 1:nrow(mapping.col)) {
# i =32
print(i)
eval(parse(text = paste0("std.name = mapping.col[",i,",'",new_name,"']")))
eval(parse(text = paste0("data.name = mapping.col[",i,",'",old_name,"']")))
if(data.name %in% colnames(data)){
setnames(data, old=c(data.name), new = c(std.name))
}
}
return(data)
}
Mapping.col is referred to the image
You can rename multiple colums at the same time, and there's no need to move the data itself that's stored in your data.frame. If you know the right order, you can just use
names(data) <- mapping.col$new_name
If the order is different, you can use match to first match them to the right positions:
names(data) <- mapping.col$new_name[match(names(data), mapping.col$old_name)]
By the way, assigning names and other attributes is always done by some sort of assignment. The setNames returns something, that still needs assigning.