不循环地为列赋值

Assign values to column without looping

我有以下数据集:

   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

我正在尝试在“lm”列中为共享相同“BLOOM”编号的列分配“LETRA”列等于“A”时的值。例如,BLOOM = 201,“lm”列的前 3 行将为 110.34。

我通过 for 循环实现了这个:

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
  }
}

提供正确结果的:

   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 

但是考虑到我的数据集的长度,这是非常低效的,我想知道是否有更有效的方法。

到目前为止,我对 dlpyr 的尝试没有成功:

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

此代码似乎没有对我的数据框进行任何更改。

有什么想法吗?

你很接近:

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

尽管这不是最佳选择,但您可以通过以下方法实现 case_when:

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