R:根据同一实例中的其他属性在data.frame中选择单元格

时间:2010-11-14 13:12:09

标签: r selection dataframe

好的,标题可能不是最具描述性的。用一个例子来解释会更容易。

我有一个像这样的data.frame:

A B 1 2
L M 3 0
P Q 5 6

如果col3>我想在第1列输出一个单元格的数组。如果col3< = col4,则col4或col2中的单元格。此data.frame的输出向量为B, L, Q

我知道我还没有很好地解释我的问题,所以这就是命令式语言的样子:

vector = []
for each rows as row
  if row[3] > row[4]
    vector.add(row[1])
  else
    vector.add(row[2])
return vector

如果这个问题已经得到解答我很抱歉,但不幸的是,谷歌在R问题方面没有多大帮助。

谢谢, 安德烈亚斯

2 个答案:

答案 0 :(得分:4)

您的测试用例不足以暴露R中与class == factor对象相关的一些潜伏鳄鱼,data.frame()的默认选项以及apply和ifelse等函数的使用。我可以为答案的长度道歉,但它实际上只是您在The R Inferno中可以阅读的内容的一小部分。假设你创建了一个data.frame,dfrm:

dfrm <-data.frame(textConnection("A  B  2  12
L  M  3  0
P  Q  5  6", header=FALSE)

注意:我稍微修改了你的第一个案例。现在运行第一个解决方案:你得到

 apply(dfrm, 1, function(x){ifelse(x[3] > x[4], x[1], x[2])})
[1] "A" "L" "P"

显然2不大于12,所以发生了什么? apply函数在矩阵上工作,并在执行函数之前将data.frame转换为矩阵并测试“2”&gt; “12”是真的。所以鳄鱼#1是apply()的默认行为。

错误或警告也可能源于第一眼和第二眼看起来完全合情合理的R代码:

vector <- dfrm$V2; 
vector[V3 > V4] <- V1[V3 > V4]

(对我来说,这不是一个特别丰富的错误信息,......关于NA的事情......这是因为我试图为一个因子对象分配一个值没有现有的水平。) 这是第二条鳄鱼:给予data.frame函数的字符值的默认类是“factor”而不是“character”。

第三条鳄鱼是ifelse的行为:

 with(dfrm, ifelse(V3 > V4, V1, V2) )
[1] 1 2 3

WTF? ifelse函数自动将V1和V2中的因子转换为它们的内部数值表示,并且它正在这样做,因为该函数根据条件参数的类型强制返回值。不是我设计这样一个功能的方式,但是这些东西在几十年前就已经解决了,所以改变它们几乎是不可能的。所以有几种“正确的”,或者至少更安全的方式来完成你要求的工作: 方法一:

with(dfrm, ifelse(V3 > V4, as.character(V1), as.character(V2) ) )  
[1] "B" "L" "Q"

方法2:

vector <- as.character(dfrm$V2)  
vector[which(dfrm$V3 > dfrm$V4)] <- as.character(dfrm$V1[which(dfrm$V3 > dfrm$V4)])  
vector  
[1] "B" "L" "Q"

答案 1 :(得分:3)

这应该有效(假设df是您的数据框)

apply(df, 1, function(x){ifelse(x[3] > x[4], x[1], x[2])})