R比较数据帧中的列以匹配值

时间:2015-10-06 15:17:49

标签: r for-loop compare

我有两个数据框,查看房屋(n = 6)和某些日期(n = 22)。

  • ORIGINAL 是原始数据集。它包含5个变量的38个观测值。并非所有房屋都列出了所有日期,反之亦然,导致使用不同长度变量的计算错误。

  • SAMPLE 是一个新的空数据集。它包含对相同5个变量的132(6 x 22)个观测值。现在每个家庭都会观察每个日期。

    众议院日猫鼬水果大象

         A       1      40        7      0.6
         A       6      32        12     4.2
         B       2      50        3      4.0 
         B       4      51        4      8.6
         B       6       8        7      12.1  
         C       2      12        8      13.0
    

我试图通过要求R比较两个数据帧之间的HouseID和Date来填补SAMPLE的其余部分;如果它们匹配,其余的变量(猫鼬,水果,大象)应该被复制用于该观察。

我试过这个无济于事......

 for(i in 1:nrow(original))
{
  if ((sample$Day == original$Day) && (sample$House == original$House)) 
  {
    sample$Mongoose[i]  <- original$Mongoose[i] 
    sample$Fruit[i]     <- original$Fruit[i] 
    sample$Elephant[i]  <- original$Elephant[i] 
  }
}

以下结果:

我按顺序得到以下3个错误

  • 在示例$ Day == test $ Day中:较长的对象长度不是倍数 较短的物体长度

  • 在is.na(e1)|中is.na(e2):较长的物体长度不是
    的倍数 较短的物体长度

  • ==.default中(示例$ House,测试$ House):较长的对象长度为
    不是较短物体长度的倍数

数据会复制,但不正确。所有的价值都转移到A房和连续日期,而不是相应的房屋和日期。

即,它看起来像这样

House   Day   Mongoose   Fruit  Elephant 
 A       1      40        7      0.6
 A       2      50        3      4.0
 A       3      51        4      8.6
 A       4       8        7      12.1
 A       5      12        8      13.0
 A       6      32        12     4.2
 B       1 
 B       2 
 B       3 [...]  

什么时候(实质上)应该是这样的:

House   Day   Mongoose   Fruit  Elephant 
 A       1      40        7      0.6
 A       2    
 A       3     
 A       4      
 A       5      
 A       6      32        12     4.2    [rest of A houses have no data]
 B       1 
 B       2      50        3      4.0 
 B       3   
 B       4      51        4      8.6
 B       5 
 B       6       8        7      12.1    [rest of B houses have no data]
 C       1    
 C       2      12        8      13.0

请指教;我最终将扩展此技术以查看具有198K条目的样本数据集和具有115K的测试数据集。

谢谢!

2 个答案:

答案 0 :(得分:1)

听起来像这应该有用:

merge(sample, original, by = c("House", "Day"), all.x = TRUE)

但没有可重复的例子很难说。您可能还想查看dplyr::left_join()。也就是说,假设您的数据如下所示:

sample <- data.frame(House = rep(c("A", "B", "C"), each = 6),
                     Day = rep(1:6, 3))

# head(sample)
#   House Day
# 1     A   1
# 2     A   2
# 3     A   3
# 4     A   4
# 5     A   5
# 6     A   6

original <- data.frame(House = c("A", "A", "B", "B", "C"),
                       Day = c(1, 6, 2, 4, 2),
                       Mongoose = c(40, 32, 50, 51, 8),
                       Fruit = c(7, 12, 3, 4, 8),
                       Elephant = c(0.6, 4.2, 4.0, 8.6, 12.1))

# head(original)
#   House Day Mongoose Fruit Elephant
# 1     A   1       40     7      0.6
# 2     A   6       32    12      4.2
# 3     B   2       50     3      4.0
# 4     B   4       51     4      8.6
# 5     C   2        8     8     12.1

我们获得:

# head(merge(sample, original, by = c("House", "Day"), all.x = TRUE))
#   House Day Mongoose Fruit Elephant
# 1     A   1       40     7      0.6
# 2     A   2       NA    NA       NA
# 3     A   3       NA    NA       NA
# 4     A   4       NA    NA       NA
# 5     A   5       NA    NA       NA
# 6     A   6       32    12      4.2

答案 1 :(得分:0)

这可能是一个小小的调整,看看原始代码的这一行:

if ((sample$Day == original$Day) && (sample$House == original$House)) 

看看你是否可以改为:

if ((sample$Day[i] == original$Day[i]) && (sample$House[i] == original$House[i]))

由于:

  • 您正在使用for循环和i变量
  • 您可以使用sample$Mongoose[i] <- original$Mongoose[i]
  • 等行做得很好
  • 但在您的示例中,似乎if语句实际上并未使用i变量
  • 所以我们修改它以使用i,因此它会专门比较观察/行sample$Day与观察/行的original$Daysample$House相同} vs original$House