【问题标题】:How to compare df1 and df2 of unequal length and assign values in R如何比较长度不等的df1和df2并在R中赋值
【发布时间】:2011-12-04 09:45:51
【问题描述】:

这些是df1和df2的定义:

df1 <- data.frame(x = 1:3, y=letters[1:3])
df2 <- data.frame(x= rep(c(1,2,3),each=3))

我想将 df1 中 y 列的值赋给 df2 中的 y 列,其中 df1 的 x 列的值等于 df2 的 x 列的值。如上图df1和df2长度不等。

for(i in 1:length(df2$x)){
        df2$y[i]<- df1$y[which(df1$x == df2$x[i])]
}

我不是在寻找捷径来做到这一点(请不要使用内置函数)。我想以正确的方式学习它。

我的逻辑正确吗? 如果是,为什么这不起作用?

我们将不胜感激。

【问题讨论】:

  • 当然“正确的方法”是简单地调用merge(df1,df2)而不是重新发明轮子?
  • @aix 我同意上述评论,但我不认为他试图重新发明轮子。我认为他试图了解轮子是如何工作的,或者至少他认为轮子是如何工作的。这是一项值得尊敬的努力!

标签: r


【解决方案1】:

采用所谓的“快捷方式”实际上是在 R 中做事的正确方法。但我确实认为手动循环有时是一种很好的练习。但是在您的“生产代码”中,即您想要依赖的代码中,请在适用时使用内置函数。

您的data.frame 只是缺少一个选项。其他一切都很好。问题在于,默认情况下,字符向量在data.frame 中作为factors 输入,当您尝试用factor 向量中的值替换值时,它会将其替换为该级别的基础数字索引。完整代码如下:

df1 <- data.frame(x = 1:3, y=letters[1:3], stringsAsFactors=FALSE)

df2 <- data.frame(x= rep(c(1,2,3),each=3))

for(i in 1:length(df2$x)){

    df2$y[i]<- df1$y[which(df1$x == df2$x[i])]
}
df2
  x y
1 1 a
2 1 a
3 1 a
4 2 b
5 2 b
6 2 b
7 3 c
8 3 c
9 3 c

有关stringsAsFactors 选项的更多信息,请参阅?data.frame

既然您似乎对学习感兴趣,那么您可能已经采用了一种调试方法。假设您的原始命令位于名为temp.R 的文件中。那么

> source('temp.R')
> ls()
[1] "df1" "df2" "i"

i 在 for 循环之后留下。让我们使用它,以便您的以下带有i 的命令将起作用。您可以将值重新分配给 i 以查看您的命令将为其他值提供什么。现在让我们开始分解代码,看看问题出在哪里。

> i
[1] 9
> which(df1$x == df2$x[i])
[1] 3

目前看起来不错。 3 是我们所期望的,对吧?

> df1$y[which(df1$x == df2$x[i])]
[1] c
Levels: a b c

在这里您需要认识到“哦,这是一个因素!”。每当您看到“级别”时,“因素”灯泡应该会在您的脑海中亮起。

在我们尝试替换之前让我们看看值,以确保您的其余代码没有意外修改它:

> df2$y[9]
[1] 3

看起来不错。我们知道替换后会发生什么,因此很明显分配出现了问题。让我们尝试一下,看看会发生什么:

> df2$y[9] <- as.factor("c")
> df2$y[9]
[1] 1

很明显有些不对劲。因此,我们将问题缩小到这里。现在我们需要回过头来找出为什么我们要用一个因子来替换。希望这将引导您获得data.frame 帮助。

这样的事情在R 中很烦人,但你只需要相信这样的行为是有原因的,一旦你在R 中学习更多编码以及更多R 的哲学,你就赢了不会有那么多这样的惊喜。祝你好运!

【讨论】:

  • 嗨,徐,我感激不尽。我整个周末都在为此工作,变得非常沮丧
  • 嗨,徐,我感激不尽。我整个周末都在为此工作,变得非常沮丧。我想放弃 R ......开个玩笑。
  • @user1079898 是的,我知道你的意思,但不要绝望!大多数人与 R 的关系是爱恨交织的关系。但是关系持续的时间越长,爱就越多:)
  • 我听到你的朋友......我认为它会持续下去......如果我遇到困难,我有像你这样的专家来帮助......谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
相关资源
最近更新 更多