Subsetting everything but a given index in a list (R) - r

Suppose I have a list of data frames. I am iterating through the list and removing one item (aka one data frame) of the list, and then rbinding the remaining items (aka data frames) of the list to create one final dataframe.
Can you help me how to remove a given index from a list and keep the rest?
Thanks!!! Example code below
testDF1 = data.frame(a = c(1,2,3,4,5), b = c(10,20,30,40,50))
testDF2 = data.frame(a = c(11,12,13,14,15), b = c(110,120,130,140,150))
testDF3 = data.frame(a = c(21,22,23,24,25), b = c(210,220,230,240,250))
testDF4 = data.frame(a = c(31,32,33,34,35), b = c(310,320,330,340,350))
testDF5 = data.frame(a = c(41,42,43,44,45), b = c(410,420,430,440,450))
myList = list(DF1 = testDF1, DF2 = testDF2, DF3 = testDF3, DF4 = testDF4, DF5 = testDF5)
for (i in 1:length(myList)) {
chosenItem = myList[[i]]
removedItemList = myList - chosenItem ## HELP HERE!!!!
updatedList = do.call("rbind", removedItemList)
}

I just figured it out...
for (i in 1:length(myList)) {
chosenItem = myList[[i]]
removedItemList = myList[i]
updatedList = do.call("rbind", removedItemList)
}

Related

How to use list elements as plot title in r?

I have this kind of data:
d<- list(d1 = list(`1979` = 3.8234619080332, `1980` = 3.94835997755299,
`1981` = 4.40780893307071), d2 = list(`1979` = 3.78682062013644,
`1980` = 3.89720895853959, `1981` = 4.35137469930167))
I am trying to plot my data and I want to use the list names d1 and d2 as plot titles.
I have tried this function with lapply;
fun1<-function(x) {
y<-x
x<-unlist(x)
plot(ecdf(x), main=deparse(substitute(y)))
}
lapply(d, fun1)
What I got are:
But I want to see d1 for the first plot and d2 for the second plot as the main title name instead of "list(d1 = list(1979 = 3.823461...."
You could use mapply to loop over both d and names(d) to pass the name of the list element to your function:
d<- list(d1 = list(`1979` = 3.8234619080332, `1980` = 3.94835997755299,
`1981` = 4.40780893307071), d2 = list(`1979` = 3.78682062013644,
`1980` = 3.89720895853959, `1981` = 4.35137469930167))
fun1<-function(x, y) {
plot(ecdf(unlist(x)), main=y)
}
mapply(fun1, d, names(d))
You could include the lapply() in your function and use the names().
fun1 <- function(d) {
nm <- names(d)
lapply(nm, function(i) plot(ecdf(unlist(d[[i]])), main=i))
}
op <- par(mfrow=c(1, 2))
fun1(d)
par(op)
Using purrr::imap -
fun1<-function(x, y) {
plot(ecdf(unlist(x)), main=y)
}
purrr::imap(d, fun1)

R Loop over triple nested list

I have got a triple nested list in R. The structure is like my testlist down below:
df_yes = data.frame(replicate(2,sample(0:130,30,rep=TRUE)))
df_no = data.frame(replicate(2,sample(0:130,20,rep=TRUE)))
s1 = list(df_yes, df_no)
names(s1) = c("yes", "no")
df_yes = data.frame(replicate(2,sample(0:130,25,rep=TRUE)))
df_no = data.frame(replicate(2,sample(0:130,15,rep=TRUE)))
s2 = list(df_yes, df_no)
names(s2) = c("yes", "no")
DJF = list(s1, s2)
names(DJF) = c("s1", "s2")
df_yes = data.frame(replicate(2,sample(0:130,60,rep=TRUE)))
df_no = data.frame(replicate(2,sample(0:130,10,rep=TRUE)))
s1 = list(df_yes, df_no)
names(s1) = c("yes", "no")
df_yes = data.frame(replicate(2,sample(0:530,25,rep=TRUE)))
df_no = data.frame(replicate(2,sample(0:230,15,rep=TRUE)))
s2 = list(df_yes, df_no)
names(s2) = c("yes", "no")
JJA = list(s1, s2)
names(JJA) = c("s1", "s2")
total_list = list(DJF, JJA)
names(total_list) = c("DJF", "JJA")
I want to add now $x3 and $x4 in the yes and no dataframes. The content should be the first number of x1 for x3) and the first number of x2 for x4.
I know how to do that with a single dataframe or a simple nested list:
df1 = total_list$DJF$s1$yes
df1$x3 = substr(df1$X1, 1,1)
df1$x4 = substr(df1$X2, 1,1)
Or with a loop in a normal list:
for(i in 1:length(df)){
df[[i]]$v3 = substr(df[[i]][,1], 1,1)}
But how can I access a triple nested list with a loop? Do I have to make a double loop with 2 variables, like [[i]][[k]][[1]]?
this will not the most suitable solution,hope this will work
N <- names(total_list)
for (i in 1:length(N)) {
name1 <- N[i]
product1 = total_list[[name1]]
K <- names(product1)
for (n in 1:length(K)) {
name2 <- K[n]
product2 = product1[[n]]
dfnames = names(product2)
for (l in dfnames) {
df_t = product2[[l]]
df_t$x3 = substr(df_t$X1, 1,1)
df_t$x4 = substr(df_t$X2, 1,1)
df_t$x3 <- as.numeric(df_t$x3)
df_t$x4 <- as.numeric(df_t$x4)
total_list[[name1]][[name2]][[l]] <- df_t
}
}
}

Populating a Data Frame with Characters in a For Loop R

Currently I have a loop that is adding rows from one data frame into another master data frame. Unfortunately, it converts the characters into numbers, but I don't want that. How can I get the following for loop to add the rows from one data frame into the master data frame while keeping the characters?
AnnotationsD <- data.frame(x = vector(mode = "numeric",
length = length(x)), type = 0, label = 0, lesion = 0)
x = c(1,2)
for(i in length(x)){
D = data.frame(x = i, type = c("Distance"),
label = c("*"), lesion = c("Wild"))
AnnotationsD[[i,]] <- D[[i]]
}
So what I would like to come out of this is:
x type label lesion
1 1 Distance * Wild
2 2 Distance * Wild
This should work:
x = c(1,2)
AnnotationsD <- data.frame(x = as.character(NA), type = as.character(NA),
label = as.character(NA), lesion = as.character(NA),
stringsAsFactors =F)
for(i in 1:length(x)){
D = c(x = as.character(i), type = as.character("Distance"),
label = as.character("*"), lesion = as.character("Wild"))
AnnotationsD[i,] <- D
}

R: Get index names while looping through df elements

Say, I have a data frame and I need to do something with its cells and remember what cells I have changed. One way is to loop through indices with two for-loops. But is there a way to do this with one loop?
Perfectly I need something like this:
changes = data.frame(Row = character(), Col = character())
for (cell in df){
if (!(is.na(df))){
cell = do.smt(cell)
temp = list(Row = get.row(cell), Col = get.col(cell))
changes = rbind(changes,temp)
}
}
Example of what I need:
df = data.frame(A = c(1,2,3), B = c(4,5,6), C = c(7,8,9))
rownames(df) = c('a','b','c')
changes = data.frame(Row = NA, Col = NA)
for (i in rownames(df)){
for (j in colnames(df)) {
if (df[i,j] > 5) {
df[i,j] = 0
temp = list(Row = i, Col = j)
changes = rbind(changes, temp)
}
}
}
This gets rid of both loops
df = data.frame(A = c(1,2,3), B = c(4,5,6), C = c(7,8,9))
rownames(df) = c('a','b','c')
changes <- which(df > 5, arr.ind=TRUE)
df[changes] <- 0
If you want the format exactly as specified you can sort that out with
changes <- data.frame(changes,row.names=NULL)
changes$row <- rownames(df)[changes$row]
changes$col <- colnames(df)[changes$col]
and its a simple matter of sorting if you're concerned that the order of the rows matches your example output

converting a list of lists in a single list

A = data.frame( a = c(1:10), b = c(11:20) )
B = data.frame( a = c(101:110), b = c(111:120) )
C = data.frame( a = c(5:8), b = c(55:58) )
L = list(list(B,C),list(A),list(C,A),list(A,B,C),list(C))
I have a list of lists of Data Frames, L but I have to creat a single List of all the Data Frames as below (The ordering of the dataframes should remain same in L and New L.)
NewL = list( B,C,A,C,A,A,B,C,C )
Try reading the manual ;) and
unlist(L,recursive=F)

Resources