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,噢,对不起。我认为在更大的数据集中可能会出现这种情况,因为我将其推广到所有分组变量。但是我想你只是想替换这个特定的行id601
。我在这个小数据集上尝试了它。有些情况下,我已经生成了所需的输出,而OP不能,但是在他们更新了包之后,问题解决了。好的,我将尝试更新包。谢谢你好,Anoushiravan,我不知道为什么我会出现这个错误,当我尝试你的解决方案时:错误:mutate()的问题
input.1
。x输入.1
无法回收为1号。ℹ 输入.1
是跨(供应商:客户,~first(na.omit(.x))的)
。ℹ 输入。1
的大小必须为1,而不是0。ℹ 错误发生在第1组:plant=“BO”,loc=“RD”。`Hi,噢,对不起。我认为在更大的数据集中可能会出现这种情况,因为我将其推广到所有分组变量。但是我想你只是想替换这个特定的行id601
。我在这个小数据集上尝试了它。有些情况下,我已经生成了所需的输出,而OP不能,但是在他们更新了包之后,问题解决了。好的,我将尝试更新包。谢谢