2010-12-13 31 views
3

我重新编码尝试组合的条件

df$test[(df$1st==(1:3) & df$2nd <= 4)] <- 1 
df$test[(df$1st==(1:3) & df$2nd <= 5)] <- 2 
df$test[(df$1st==(1:3) & df$2nd <= 6)] <- 3 

导致"longer object length is not a multiple of shorter object length"预警和df$test很多NA S,即使一些重新编码正常工作。
我错过了什么?任何帮助赞赏。

DW

回答

4

我不知道你想实现与df$1st==(1:3)什么,但它可能不会做你认为它。它recyclesc(1,2,3)尽可能多的时间,使其只要df

如果你想检查是否df$1st是1和3之间,你可能想拼出来:

df$1st>=1 & df$1st<=3 
+0

非常感谢aix!问题确实是1:3;拼写出来工作。 – dw006 2010-12-13 11:58:35

+0

+1供参考。 – Marek 2010-12-13 14:05:30

5

问题是在这一行:

df$1st==(1:3) 

你可以使用%in%

df$1st %in% (1:3) 

警告来了,因为你比较不同长度的向量(1:3有长度3和df$1st有长度“只有你知道什么”)。

身边我想你错过了你的价值观将被覆盖:df$2nd <= 4df$2nd <= 6因此所有1和2是由覆盖3

+0

对不起,覆盖只发生在我的例子中,我放下了太快和错误... – dw006 2010-12-13 12:00:42

1

您可能还需要考虑使用transform()处理重新编码此类问题。 transform()将执行比逻辑索引方法慢的速度,但更容易消化代码的意图。关于不同方法的优缺点可以参考here。试想一下:

set.seed(42) 
df <- data.frame("first" = sample(1:5, 10e5, TRUE), "second" = sample(4:8, 10e5, TRUE)) 

df <- transform(df 
    , test =  ifelse(first %in% 1:3 & second == 4, 1 
      , ifelse(first %in% 1:3 & second == 5, 2 
      , ifelse(first %in% 1:3 & second == 6, 3, NA))) 
    ) 

其次,列名1st2nd不是语法有效的列名。查看make.names()了解有效列名称的更多详细信息。使用data.frame时,可以使用/滥用check.names参数。例如:

> df <- data.frame("1st" = sample(1:5, 10e5, TRUE), "2nd" = sample(4:8, 10e5, TRUE), check.names = FALSE) 
> colnames(df) 
[1] "1st" "2nd" 
> df <- data.frame("1st" = sample(1:5, 10e5, TRUE), "2nd" = sample(4:8, 10e5, TRUE), check.names = TRUE) 
> colnames(df) 
[1] "X1st" "X2nd"