R:比较多个列对,并将值放在新的相应变量上

R:比较多个列对,并将值放在新的相应变量上,r,R,我是一个基本的R用户 在我想要收集数据的同一数据帧中,每个“id”有50个列对(示例对为:“pair_q1”和“pair_01_v_rde”),并将其放入新的相应变量中,例如“newvar_q1” 所有pair变量名在其名称中都有一个模式,可以提炼成这样(“pair_qX”和“pair_X_v_rde”,其中X=1:50,我想要的最后一个变量是“newvar_qX”,其中X=1:50) 理想情况下,数据对中只有一个成员应该包含数据,但事实并非如此 每个变量都可以包含1:5或NA(缺失)的值 根据

我是一个基本的R用户

在我想要收集数据的同一数据帧中,每个“id”有50个列对(示例对为:“pair_q1”和“pair_01_v_rde”),并将其放入新的相应变量中,例如“newvar_q1”

所有pair变量名在其名称中都有一个模式,可以提炼成这样(“pair_qX”和“pair_X_v_rde”,其中X=1:50,我想要的最后一个变量是“newvar_qX”,其中X=1:50)

理想情况下,数据对中只有一个成员应该包含数据,但事实并非如此

每个变量都可以包含1:5或NA(缺失)的值

根据“id”从每对数据中收集数据的规则以及在新创建的相应变量中放置的内容是:

如果其中一对具有值,而另一对缺失,则将该值放入相应的新变量中。e、 g.(“pair_q1”=1和“pair_01_v_rde”=NA然后“newvar_q1”=1)

如果两对具有相同的值或两者都缺失,则将该值/缺失放在其相应的新变量中,例如(“pair_q50”=1/NA和“pair_50_v_rde”=1/NA,然后“newvar_q50”=1/NA)

如果两个对具有不同的值,则忽略这两个值并分配其相应的新变量999,例如(“pair_q02”=3和“pair_02_v_rde”=2,然后“newvar_q02”=999)

有人能告诉我如何在R中执行此操作吗

谢谢! 耐莉

#创建玩具数据集

id使用“tidyverse”(使用“inner_join(mydata,,,by=“id”)”按您在问题中给出的顺序获取新列)的可能解决方案:


谢谢你,尼古拉斯。它的工作如预期。对于我和未来的R新手,你能评论一下每行代码都在做什么吗?@Nelly我希望用有用的评论编辑了我的答案。谢谢@尼古拉斯2
# Create Toy dataset
id <- c(100, 101, 102)
pair_q1 <- c(1, NA, 1)
pair_01_v_rde <- c(NA, 2, 1)
pair_q2 <- c(1, 1, NA)
pair_02_v_rde <- c(2, NA, NA)
pair_q50 <- c(NA, 2, 4)
pair_50_v_rde <- c(4, 3, 1)

mydata <- data.frame(id, pair_q1, pair_01_v_rde, pair_q2, pair_02_v_rde, pair_q50, pair_50_v_rde)


# The dataset
> mydata
id pair_q1 pair_01_v_rde pair_q2 pair_02_v_rde pair_q50 pair_50_v_rde
1 100       1            NA       1             2       NA             4
2 101      NA             2       1            NA        2             3
3 102       1             1      NA            NA        4             1


# Here I manually build what I would like to have in the dataset 
newvar_q1 <- c(1, 2, 1)
newvar_q2 <- c(999, 1, NA)
newvar_q50 <- c(4, 999, 999)


mydata2 <- data.frame(id, pair_q1, pair_01_v_rde, pair_q2, pair_02_v_rde, pair_q50, pair_50_v_rde, newvar_q1, newvar_q2, newvar_q50)

> mydata2

id pair_q1 pair_01_v_rde pair_q2 pair_02_v_rde pair_q50 pair_50_v_rde newvar_q1 newvar_q2 newvar_q50
1 100       1            NA       1             2       NA             4         1       999          4
2 101      NA             2       1            NA        2             3         2         1        999
3 102       1             1      NA            NA        4             1         1        NA        999
mydata %>% 
  select(id,matches("^pair_q")) %>%                  # keeps only left part of pairs
  gather(k,v1,-id) %>%                               # transforms into tuples (id,variable name,variable value)
  mutate(n=as.integer(str_extract(k,"\\d+"))) -> df1 # converts variable name into variable number
mydata %>% 
  select(id,matches("^pair_\\d")) %>%                # same on right part of pairs 
  gather(k,v2,-id) %>% 
  mutate(n=as.integer(str_extract(k,"\\d+"))) -> df2

inner_join(df1,df2,by=c("id","n")) %>% 
  mutate(w=case_when(is.na(v1) ~ v2,      # builds new variable value
                     is.na(v2) ~ v1,      # from your rules
                     v1==v2 ~ v1,
                     TRUE ~999),
        k=paste0("newvar_q",n)) %>%        # builds new variable name from variable number
  select(id,k,w) %>%                       # keeps only useful columns
  spread(k,w) %>%                          # switches back from tuple view to wide view 
  inner_join(mydata,by="id")               # and merges the new variables to the original data

#   id newvar_q1 newvar_q2 newvar_q50 pair_q1 pair_01_v_rde pair_q2 pair_02_v_rde pair_q50 pair_50_v_rde
#1 100         1       999          4       1            NA       1                 #2       NA             4
#2 101         2         1        999      NA             2       1            NA        2             3
#3 102         1        NA        999       1             1      NA            NA        4             1