【问题标题】:adding values from one column of a data frame into a new column of another dataframe if the first two columns in both match如果前两列都匹配,则将数据框的一列中的值添加到另一个数据框的新列中
【发布时间】:2018-03-01 10:10:23
【问题描述】:

我有一个包含 35K 点和 2 列的数据框 (d1)。我有第二个数据框(d2),有 352 个点和 3 列。我一直在尝试做的是如果 d1$c1 和 d1$c2 等于 d2$c1 和 d2$c2,那么我想将 d2$c3 的值添加到 d1 的新列中(比如 d1$c3 )。 数据帧 d1 类似于下面的数据帧。 D2 基本上是 D1 的小版本,而 D1 的相同值重复了多次

**D1**
|C1 | C2  |      
|---|:---:|
|1  |1    |
|1  |1    |
|1  |2    |
|2  |1    |
|2  |2    |
|2  |2    |
|2  |2    |
|3  |1    |
|3  |2    |
|3  |3    |
|3  |1    |
|3  |1    |

**D2**

|C1 | C2  | C3  |
|---|:---:|----:|
|1  |1    |a    |
|1  |2    |b    |
|1  |3    |c    | 
|2  |2    |b    |
|3  |1    |c    |   
|3  |2    |a    |
|3  |3    |b    | 

现在我想做的是这个

if((d1$c1 == d2$c1) & (d1$c2 == d2$c2))
{
d1$c3 = d2$c3
}

运行循环后,生成的 D1 应该类似于 D2 中的匹配条目,被添加到 D1 中的新列中

 **D1**
    |C1 | C2  | new C3|      
    |---|:---:|--------
    |1  |1    |a
    |1  |1    |a
    |1  |2    |b
    |2  |1    |a
    |2  |2    |b
    |2  |2    |b
    |2  |2    |b
    |3  |1    |c
    |3  |2    |a
    |3  |3    |b
    |3  |1    |c
    |3  |1    |c

但我最终会收到长度不匹配的错误。

我试过的代码是

for(i in 1:length(D1$c1))
{
if(((D1$C1 = D2$c1) & (D1$C2 = D2$c2))
{
  D1$c3[i] = D2$c3
}
}

我还尝试使用一列创建一个新数据框以添加来自 D2 的值

x = data.frame(length(D1))

for(i in (D1$C1 & D1$C2))
{
  for(j in D2$C1 & D2$C2)
  {
    if(i == j)
    { 
      x = (D2$C3)
              }
  }
}

这两个都没有用。

【问题讨论】:

  • 看来你要使用merge函数

标签: r for-loop dataframe


【解决方案1】:
library(dplyr)
df1 <- df1 %>%
  left_join(df2, by=c("C1","C2"))

输出是:

   C1 C2   C3
1   1  1    a
2   1  1    a
3   1  2    b
4   2  1 <NA>
5   2  2    b
6   2  2    b
7   2  2    b
8   3  1    c
9   3  2    a
10  3  3    b
11  3  1    c
12  3  1    c

样本数据:

df1 <- structure(list(C1 = c(1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3), C2 = c(1, 
1, 2, 1, 2, 2, 2, 1, 2, 3, 1, 1)), .Names = c("C1", "C2"), class = "data.frame", row.names = c(NA, 
-12L))

df2 <- structure(list(C1 = c(1, 1, 1, 2, 3, 3, 3), C2 = c(1, 2, 3, 2, 
1, 2, 3), C3 = c("a", "b", "c", "b", "c", "a", "b")), .Names = c("C1", 
"C2", "C3"), row.names = c(NA, -7L), class = "data.frame")

【讨论】:

  • 抱歉我的错误没有以正确的方式表达数据框。具有 35k 点的较长数据帧的列名与具有 352 个点的较短 df、d2 不同。如果我只是重命名具有相同名称的列,这会起作用吗?
  • 对不起,我只是在上面的评论中提到了一个疑问。回答完毕后,我会将其标记为已关闭。
  • 重命名列可能是一种选择。如果您不想重命名,那么上述代码中的这个小改动可能会有所帮助 - left_join(df2, by=c("df1_C1_columnname"="df2_C1_columnname", "df1_C2_columnname" = "df2_C2_columnname"))
【解决方案2】:

用base R,就是合并函数:

set.seed(654321)
d1 <- data.frame(C1=rep(1:3, each=6), C2=sample(3, 6*3, replace=TRUE))
d2 <- data.frame(C1=rep(1:3, 3), C2=rep(1:3, each=3), C3=sample(letters[1:3], 9, replace=TRUE))
merge(d1, d2, by=c("C1", "C2"))

【讨论】:

  • 抱歉我的错误没有以正确的方式表达数据框。具有 35k 点的较长数据帧的列名与具有 352 个点的较短 df、d2 不同。如果我只是重命名具有相同名称的列,这会起作用吗?
  • 然后可以使用 by.x=c() 和 by.y=c() 来指定不同的列
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多