当前位置: 首页 > 知识库问答 >
问题:

如何用另一个数据帧中的数据填充一个数据帧,同时保留第一个数据帧中的NAs

从开济
2023-03-14

我有两个数据帧,它们的列名相同,但行数不同。第一个数据帧(a)看起来与此类似:

a = data.frame("Site"=c(1,2,3,4,7,9,10,11,13,14), 
               "v1"=c(0,0,0,0,0,0,0,0,0,0), 
               "v2"=c(0,0,0,0,NA,NA,NA,0,0,0), 
               "v3"=c(0,0,0,NA,0,NA,0,0,0,0), 
               "v4"=c(0,0,0,0,0,0,0,0,NA,NA), 
               "v5"=c(0,0,0,0,0,NA,0,NA,0,0)) 

注:站点5、6、8和12故意丢失。

第二个数据帧(b)看起来像这样:

b = data.frame("Site"=c(2,3,4,7,10,14),
               "v1"=c(1,NA,2,1,NA,NA),
               "v2"=c(1,1,NA,NA,NA,NA),
               "v3"=c(NA,1,NA,NA,NA,1),
               "v4"=c(1,NA,4,1,NA,NA),
               "v5"=c(1,NA,2,1,1,3))

我想要实现的是:

desired = data.frame("Site"=c(1,2,3,4,7,9,10,11,13,14), 
                     "v1"=c(0,1,0,2,1,0,0,0,0,0), 
                     "v2"=c(0,1,1,0,NA,NA,NA,0,0,0), 
                     "v3"=c(0,0,1,NA,0,NA,0,0,0,1), 
                     "v4"=c(0,1,0,4,1,0,0,0,NA,NA), 
                     "v5"=c(0,1,0,2,1,NA,1,NA,0,3))

在那里我注入(我肯定有一个更好的术语)数据帧b到数据帧a的数据,但是我想用零替换b中的任何NAs,并保持a中的NAs不变。

我发现并尝试了这个代码:

cols <- colnames(a)[colnames(a) %in% colnames(b)]
rows <- rownames(a)[rownames(a) %in% rownames(b)]

a[rows, cols] <- b[rows, cols]

但它会带来NAs。我考虑先将NAs替换为零,但即使如此,它也会抹去我目前在数据帧a中想要保留的NAs。

也许tidyverse中的for循环或其他东西是一个不错的选择,但我甚至不知道从哪里开始。任何帮助都将不胜感激!

共有3个答案

洪安顺
2023-03-14
i <- match(b$Site, a$Site)
a_nas <- is.na(a)
for (j in seq(2, ncol(a))) {
  a[i, j] <- ifelse(is.na(b[[j]]), 0, b[[j]])
}
a[a_nas] <- NA

all.equal(desired, a)
# [1] TRUE
温亮
2023-03-14
merge(b, a, by = 'Site', all = TRUE) %>%
  split.default(sub('.x|.y', '', names(.))) %>%
  map_df(~coalesce(!!!.x))

# A tibble: 10 x 6
    Site    v1    v2    v3    v4    v5
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1     1     0     0     0     0     0
 2     2     1     1     0     1     1
 3     3     0     1     1     0     0
 4     4     2     0    NA     4     2
 5     7     1    NA     0     1     1
 6     9     0    NA    NA     0    NA
 7    10     0    NA     0     0     1
 8    11     0     0     0     0    NA
 9    13     0     0     0    NA     0
10    14     0     0     1    NA     3
苏波涛
2023-03-14

我建议您首先用0替换b中的每个NA值,然后使用internal\u join将结果与a中相应的站点值合并。然后,您可以将a的非NA值替换为b中的相应值,使a中的NA值保持不变。最后,我们将修改后的数据框与a的子集绑定,该子集的Site值在b中不存在。

library(dplyr)

a %>%
  inner_join(b %>%
               mutate(across(!Site, ~ replace(.x, is.na(.x), 0))), 
             by = "Site") %>%
  mutate(across(ends_with(".x"), ~ ifelse(!is.na(.x), get(gsub("(.*\\.)x", "\\1y", cur_column())), 
                                          .x))) %>%
  select(!ends_with("y")) %>%
  rename_with(~ gsub("(.*)\\.x", "\\1", .), ends_with(".x")) %>%
  bind_rows(a %>% 
              filter(!Site %in% unique(b$Site))) %>%
  arrange(Site)


   Site v1 v2 v3 v4 v5
1     1  0  0  0  0  0
2     2  1  1  0  1  1
3     3  0  1  1  0  0
4     4  2  0 NA  4  2
5     7  1 NA  0  1  1
6     9  0 NA NA  0 NA
7    10  0 NA  0  0  1
8    11  0  0  0  0 NA
9    13  0  0  0 NA  0
10   14  0  0  1 NA  3

也是我杰出的朋友Onyanbu提出的一个卓越而简洁的解决方案:

rbind(a, b) %>% 
  group_by(Site) %>%  
  summarise(across(everything(), ~ 
                     if(any(!is.na(.x))) max(.x, na.rm = TRUE) else NA))
 类似资料:
  • 我有两个Dataframes一个与日期集(df1)和另一个与emp_ids集(df2)。我试图创建一个新的Dataframe,这样df2中的每个emp_id都被标记为df1中的每个日期。 下面给出了我的数据帧的外观 df1 df2 预期产出: 我将日期列转换为字符串,并尝试执行以下操作,但返回的数据框为空 我尝试做

  • 我有两个数据帧,它们共享多个公共列,如下所示: 第一个: 而第二个: 我想保留中的行,其列也存在于中。例如,df2的第27行有值,对于,这些值并不都存在于(因为df1只对列有值

  • 我有两个数据框,都包含英文和中文单词字符串,我想知道其中一个是另一个的子集:

  • 这是我的密码: 我想知道如何将df3绑定到单个数据帧中作为"NA"s? 我在r_blogger上找到了一篇关于将向量或长度不等的数据帧组合成一个数据帧的文章。http://www.r-bloggers.com/r-combining-vectors-or-data-frames-of-unequal-length-into-one-data-frame/ 但是我从数据中得到的数据框,其中一些是空的

  • 我相信这很简单,但找不到答案。我有一个数据帧df: 然后,我有另一个较小的数据框,其中包含单元格引用(行号和列号),引用df中应为空的特定单元格(即NA): 我如何用NA替换df中所有由cellRefs中的行和列引用引用的单元格?

  • 我有2个数据帧在apache火花。 df 1有显示编号和说明。。。数据看起来像 不显示描述a这是米奇b唐纳德来了c玛丽和乔治回家d玛丽和乔治进城 第二个数据帧有字符 人物 乔治 唐纳德 玛丽 米妮 我需要搜索节目描述,找出哪个节目的特征是哪个角色... 最终输出应该如下所示 乔治|c,d 唐纳德|b 玛丽|c. d 米妮|不显示 这些数据集经过精心设计,非常简单,但它表达了我试图实现的搜索功能。我