Asked  6 Months ago    Answers:  5   Viewed   22 times

Possible Duplicate:
Merge multiple data frames in a list simultaneously

example data.frames:

 df1 = data.frame(id=c('1','73','2','10','43'),v1=c(1,2,3,4,5)) <br>
 df2 = data.frame(id=c('7','23','57','2','62','96'),v2=c(1,2,3,4,5,6)) <br>
 df3 = data.frame(id=c('23','62'),v3=c(1,2)) <br>

Note: id is unique for each data.frame. I want the resulting matrix to look like

1      1 NA NA 
2      3  4 NA 
7      NA 1 NA 
10     4 NA NA 
23     NA 2  1 
43     5 NA NA 
57     NA 3 NA 
62     NA 5  2 
73     2 NA NA 
96     NA 6 NA

In this case, I only show 3 datasets, I actually have at least 22 of them so at the end I want a matrix of nx(22+1) where n is the number of ids for all 22 datasets.

Given 2 datasets, I need to get their ids in the first column and 2nd and 3rd columns are filled with the values, if there is no value exists, then input NA instead.

 Answers

64

Put them into a list and use merge with Reduce

Reduce(function(x, y) merge(x, y, all=TRUE), list(df1, df2, df3))
#    id v1 v2 v3
# 1   1  1 NA NA
# 2  10  4 NA NA
# 3   2  3  4 NA
# 4  43  5 NA NA
# 5  73  2 NA NA
# 6  23 NA  2  1
# 7  57 NA  3 NA
# 8  62 NA  5  2
# 9   7 NA  1 NA
# 10 96 NA  6 NA

You can also use this more concise version:

Reduce(function(...) merge(..., all=TRUE), list(df1, df2, df3))
Tuesday, June 1, 2021
 
SubniC
answered 6 Months ago
92

From your description I understand that you want to replace the z values in d1 with the z values in d2 when x & y match.

Using base R:

d3 <- merge(d1, d2, by = c("x","y"), all.x = TRUE)
d3[is.na(d3$z.y),"z.y"] <- d3[is.na(d3$z.y),"z.x"]
d3 <- d3[,-3]
names(d3)[3] <- "z"

which gives:

> d3
   x  y   z
1 10 10 100
2 10 12   6
3 11 10 200
4 11 12   2
5 12 10   1
6 12 12 400

Using the data.table-package:

library(data.table)

setDT(d1) # convert the data.frame to a data.table
setDT(d2) # idem

# join the two data.table's and replace the values
d1[d2, on = .(x, y), z := i.z]

or in one go:

setDT(d1)[setDT(d2), on = .(x, y), z := i.z]

which gives:

> d1
    x  y   z
1: 10 10 100
2: 10 12   6
3: 11 10 200
4: 11 12   2
5: 12 10   1
6: 12 12 400

Using the dplyr package:

d3 <- left_join(d1, d2, by = c("x","y")) %>%
  mutate(z.y = ifelse(is.na(z.y), z.x, z.y)) %>%
  select(-z.x) %>%
  rename(z = z.y)

Since release 0.5.0 you can also use the coalesce-function for this (thx to Laurent Hostert for bringing it to my attention):

d3 <- left_join(d1, d2, by = c("x","y")) %>% 
  mutate(z = coalesce(z.y, z.x)) %>% 
  select(-c(z.x, z.y))
Friday, June 11, 2021
 
binoculars
answered 6 Months ago
73

Ok I've just discussed this situation with a colleague of mine and we've come to the following solution which works!

int amountToSkip = 0;
var finished = false;
while (!finished)
{
      using (var dataContext = new LinqToSqlContext(new DataContext()))
      {
           var objects = dataContext.Repository<Object>().Skip(amountToSkip).Take(250).ToList();
           if (objects.Count == 0)
                finished = true;
           else
           {
                foreach (Object object in objects)
                {
                    // Create 0 - 4 Random Items
                    for (int i = 0; i < Random.Next(0, 4); i++)
                    {
                        Item item = new Item();
                        item.Id = Guid.NewGuid();
                        item.Object = object.Id;
                        item.Created = DateTime.Now;
                        item.Changed = DateTime.Now;
                        dataContext.InsertOnSubmit(item);
                     }
                 }
                 dataContext.SubmitChanges();
            }
            // Cumulate amountToSkip with processAmount so we don't go over the same Items again
            amountToSkip += processAmount;
        }
}

With this implementation we dispose the Skip() and Take() cache everytime and thus don't leak memory!

Thursday, August 5, 2021
 
Chvanikoff
answered 4 Months ago
69

If this is only a single group of 'key', one option would be to use base R. We transpose (t) the dataset except the first column (df[-1]), concatenate to a vector, convert to data.frme and cbind with the first element of the first column.

res <- cbind(df1[1,1], as.data.frame.list(c(t(df1[-1]))))
names(res) <- c(names(df1)[1] ,make.unique(rep(names(df1)[-1],3)))
res
#  Key A B C A.1 B.1 C.1 A.2 B.2 C.2
#1   1 1 2 3   4   6   8   3   2   1

Or use data.table i.e. the development version v1.9.7 if there are many 'Key' elements

library(data.table)
dcast(setDT(df1), Key~rowid(Key), value.var = c("A", "B", "C"),sep="")
#   Key A1 A2 A3 B1 B2 B3 C1 C2 C3
#1:   1  1  4  3  2  6  2  3  8  1

if we have a data.table with version < v1.9.7, we need to create the sequence column grouped by 'Key'.

dcast(setDT(df1)[, rn := 1:.N , Key], Key ~rn, value.var = c("A", "B", "C"),sep="")
#   Key A1 A2 A3 B1 B2 B3 C1 C2 C3
#1:   1  1  4  3  2  6  2  3  8  1
Friday, September 3, 2021
 
Zeth
answered 3 Months ago
70

How do you initialize your RequestQueue? I suspect that you are creating RequestQueues for each tab. If that's the case, change your program to use one common instance of RequestQueue from all the tabs. You need to initialize and retain it in your activity and add requests to it from each tab.

Thursday, November 18, 2021
 
samrap
answered 2 Weeks ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share