R 根据条件将值从一行复制到另一行

R 根据条件将值从一行复制到另一行,r,dataframe,dplyr,data.table,tidyr,R,Dataframe,Dplyr,Data.table,Tidyr,我有以下数据集: # Data movmnt_id <- c("101", "601", "105", "321") plant <- c("FF", "FF", "DO", "BO") loc <- c("MM", "MM", "KB", "RD&q

我有以下数据集:

# Data
movmnt_id <- c("101", "601", "105", "321")
plant <- c("FF", "FF", "DO", "BO")
loc <- c("MM", "MM", "KB", "RD")
vendor <- c(123, NA,NA,NA)
customer <- c(456, NA,NA,NA)
check <- c(NA, NA, "defined", "defined")

df <-  data.frame(movmnt_id, plant, loc, vendor,customer,check)

  movmnt_id plant loc vendor customer   check
1       101    FF  MM    123      456    <NA>
2       601    FF  MM     NA       NA    <NA>
3       105    DO  KB     NA       NA defined
4       321    BO  RD     NA       NA defined
情况如下:

If in current row `movmnt_id `== 601 
 -> take row *WHERE* `plant` & `loc` are the same as in the current row
              *AND* `movmnt_id  == 101`
              *AND* is.na(check)
 -> copy from found row `vendor` & `customer` to the current row
我可以考虑一些for循环,但对于我的数据集,它太重了。
我想知道是否有更优雅的解决方案,计算成本更低

我试图从这些案例中调整解决方案,但没有成功:


此解决方案可能会有所帮助,但我假设这两个值复制到第二行,因为它们在
loc
&
工厂
列中共享相同的值:

library(dplyr)

df %>%
  group_by(plant, loc) %>%
  mutate(across(vendor:customer, ~ first(na.omit(.x))))

  movmnt_id plant loc   vendor customer check  
  <chr>     <chr> <chr>  <dbl>    <dbl> <chr>  
1 101       FF    MM       123      456 NA     
2 601       FF    MM       123      456 NA     
3 105       DO    KB        NA       NA defined
4 321       BO    RD        NA       NA defined
库(dplyr)
df%>%
组别(工厂、loc)%>%
变异(跨越(供应商:客户,~first(na.omit(.x)))
移动标识设备loc供应商客户检查
101FF毫米123456 NA
2 601毫米123 456纳
3 105 KB NA是否已定义
4 321 BO路不适用

此解决方案可能有帮助,但我假设这两个值复制到第二行,因为它们在
loc
&
工厂
列中共享相同的值:

library(dplyr)

df %>%
  group_by(plant, loc) %>%
  mutate(across(vendor:customer, ~ first(na.omit(.x))))

  movmnt_id plant loc   vendor customer check  
  <chr>     <chr> <chr>  <dbl>    <dbl> <chr>  
1 101       FF    MM       123      456 NA     
2 601       FF    MM       123      456 NA     
3 105       DO    KB        NA       NA defined
4 321       BO    RD        NA       NA defined
库(dplyr)
df%>%
组别(工厂、loc)%>%
变异(跨越(供应商:客户,~first(na.omit(.x)))
移动标识设备loc供应商客户检查
101FF毫米123456 NA
2 601毫米123 456纳
3 105 KB NA是否已定义
4 321 BO路不适用

要实现您的条件,您可以尝试以下方法-

library(dplyr)

df %>%
  group_by(plant, loc) %>%
  mutate(across(c(vendor, customer), 
              ~ifelse(movmnt_id == '601' & is.na(.), 
                      .[is.na(check) & movmnt_id == 101], .))) %>%
  ungroup

#  movmnt_id plant loc   vendor customer check  
#  <chr>     <chr> <chr>  <dbl>    <dbl> <chr>  
#1 101       FF    MM       123      456 NA     
#2 601       FF    MM       123      456 NA     
#3 105       DO    KB        NA       NA defined
#4 321       BO    RD        NA       NA defined
库(dplyr)
df%>%
组别(工厂、loc)%>%
变异(跨越(c)(供应商、客户),
~ifelse(movmnt_id='601'&is.na(.),
[is.na(check)&movmnt_id==101],)%>%
解组
#移动标识设备loc供应商客户检查
#                 
#101FF毫米123456 NA
#2 601毫米123 456纳
#3 105 KB NA是否已定义
#4 321 BO路不适用

要实现您的条件,您可以尝试以下方法-

library(dplyr)

df %>%
  group_by(plant, loc) %>%
  mutate(across(c(vendor, customer), 
              ~ifelse(movmnt_id == '601' & is.na(.), 
                      .[is.na(check) & movmnt_id == 101], .))) %>%
  ungroup

#  movmnt_id plant loc   vendor customer check  
#  <chr>     <chr> <chr>  <dbl>    <dbl> <chr>  
#1 101       FF    MM       123      456 NA     
#2 601       FF    MM       123      456 NA     
#3 105       DO    KB        NA       NA defined
#4 321       BO    RD        NA       NA defined
库(dplyr)
df%>%
组别(工厂、loc)%>%
变异(跨越(c)(供应商、客户),
~ifelse(movmnt_id='601'&is.na(.),
[is.na(check)&movmnt_id==101],)%>%
解组
#移动标识设备loc供应商客户检查
#                 
#101FF毫米123456 NA
#2 601毫米123 456纳
#3 105 KB NA是否已定义
#4 321 BO路不适用


谢谢你,@Ronak!它起作用了。您能解释一下条件的这一部分是什么意思吗
&is.na(.)
?我尝试过不使用它,它可以工作。它检查我们正在替换的当前值是否为
NA
。如果
vendor
中的第二行不是
NA
,则不会替换该值。请尝试使用
df$vendor[2]亲爱的Ronak Shah,请问您是否知道为什么我可以得到结果,但OP无法得到?可能与
dplyr
的版本有关吗?@AnoushiravanR我认为OP可能使用了
数据。table::first
(给出错误)而不是
dplyr::first
(没有给出错误)。虽然这可能不是OP想要的。谢谢你,@Ronak!它起作用了。您能解释一下条件的这一部分是什么意思吗
&is.na(.)
?我尝试过不使用它,它可以工作。它检查我们正在替换的当前值是否为
NA
。如果
vendor
中的第二行不是
NA
,则不会替换该值。请尝试使用
df$vendor[2]亲爱的Ronak Shah,请问您是否知道为什么我可以得到结果,但OP无法得到?可能与
dplyr
的版本有关吗?@AnoushiravanR我认为OP可能使用了
数据。table::first
(给出错误)而不是
dplyr::first
(没有给出错误)。尽管这可能不是OP想要的。嗨,Anoushiravan,我不知道为什么我会出现这个错误,当我尝试你的解决方案时:
错误:mutate()的问题
input
.1
。x输入
.1
无法回收为1号。ℹ 输入
.1
是跨(供应商:客户,~first(na.omit(.x))的
。ℹ 输入
。1
的大小必须为1,而不是0。ℹ 错误发生在第1组:plant=“BO”,loc=“RD”。`Hi,噢,对不起。我认为在更大的数据集中可能会出现这种情况,因为我将其推广到所有分组变量。但是我想你只是想替换这个特定的行id
601
。我在这个小数据集上尝试了它。有些情况下,我已经生成了所需的输出,而OP不能,但是在他们更新了包之后,问题解决了。好的,我将尝试更新包。谢谢你好,Anoushiravan,我不知道为什么我会出现这个错误,当我尝试你的解决方案时:
错误:mutate()的问题
input
.1
。x输入
.1
无法回收为1号。ℹ 输入
.1
是跨(供应商:客户,~first(na.omit(.x))的
。ℹ 输入
。1
的大小必须为1,而不是0。ℹ 错误发生在第1组:plant=“BO”,loc=“RD”。`Hi,噢,对不起。我认为在更大的数据集中可能会出现这种情况,因为我将其推广到所有分组变量。但是我想你只是想替换这个特定的行id
601
。我在这个小数据集上尝试了它。有些情况下,我已经生成了所需的输出,而OP不能,但是在他们更新了包之后,问题解决了。好的,我将尝试更新包。谢谢