Home > Software engineering >  Assign values to column without looping
Assign values to column without looping

Time:01-22

I have the following dataset:

   COLADA LETRA BLOOM         pz     lm
1  220103     A   201 220103A201 110.34
2  220103     B   201 220103B201  36.00
3  220103     Y   201 220103Y201  36.00
4  220103     A   101 220103A101 111.45
5  220103     B   101 220103B101  36.00
6  220103     Y   101 220103Y101  36.00
7  220103     A   303 220103A303 111.25
8  220103     B   303 220103B303  36.00
9  220103     Y   303 220103Y303  36.00
10 220103     A   202 220103A202 112.01
11 220103     A   401 220103A401 110.93
12 220103     A   302 220103A302 109.34

I'm trying to assign in column "lm" the value for when column "LETRA" equals "A" for those that share the same "BLOOM" number. For example, BLOOM = 201, the first 3 rows of column "lm" would be 110.34.

I have achieved this via for loop:

library(stringr)

lon <- NA
for (i in 1:length(df$pz)){ 
  if (str_detect(df$pz[i], "A")){
    lon <- df$lm[i]
  } else {
    df$lm[i] <- lon
  }
}

which offers the right result:

   COLADA LETRA BLOOM         pz     lm 
1  220103     A   201 220103A201 110.34 
2  220103     B   201 220103B201 110.34 
3  220103     Y   201 220103Y201 110.34 
4  220103     A   101 220103A101 111.45 
5  220103     B   101 220103B101 111.45 
6  220103     Y   101 220103Y101 111.45 
7  220103     A   303 220103A303 111.25 
8  220103     B   303 220103B303 111.25 
9  220103     Y   303 220103Y303 111.25 
10 220103     A   202 220103A202 112.01 
11 220103     A   401 220103A401 110.93 
12 220103     A   302 220103A302 109.34 

But given the length of my dataset this is quite inefficient and I was wondering if there's a more efficient method.

My try with dlpyr is, so far, unsuccessful:

df%>%
  group_by(BLOOM) %>%
  mutate(lm = case_when(LETRA != "A" ~ lm))

This code doesn't seem to do any changes on my dataframe.

Any ideas?

CodePudding user response:

You were close:

df %>% 
  group_by(BLOOM) %>% 
  mutate(lm = lm[LETRA == "A"])

   COLADA LETRA BLOOM         pz     lm
1  220103     A   201 220103A201 110.34
2  220103     B   201 220103B201 110.34
3  220103     Y   201 220103Y201 110.34
4  220103     A   101 220103A101 111.45
5  220103     B   101 220103B101 111.45
6  220103     Y   101 220103Y101 111.45
7  220103     A   303 220103A303 111.25
8  220103     B   303 220103B303 111.25
9  220103     Y   303 220103Y303 111.25
10 220103     A   202 220103A202 112.01
11 220103     A   401 220103A401 110.93
12 220103     A   302 220103A302 109.34

Even though this is not optimal, here is how you can do it with case_when:

df %>% 
  group_by(BLOOM) %>% 
  mutate(lm = case_when(LETRA != "A" ~ lm[LETRA == "A"],
                        T ~ lm))
  •  Tags:  
  • Related