【问题标题】:Subsetting based on values of a different data frame in R基于R中不同数据框的值的子集
【发布时间】:2013-02-26 19:22:32
【问题描述】:

如果行中的每个值都大于不同数据框中的相应行,我想对数据进行子集化。我还需要跳过一些顶行。这些以前的问题对我没有帮助,但它是相关的:

Subsetting a data frame based on contents of another data frame

Subset data using information from a different data frame [r]

> A
     name1 name2
cond   trt  ctrl
hour     0     3
A        1     1
B       10     1
C        1     1
D        1     1
E       10    10
> B
     name1 name2
cond   trt  ctrl
hour     0     3
A        1     1
B        1    10
C        1     1
D        1     1
E        1     1

我想要这个。只有 A 中所有值都大于 B 的行:

     name1 name2
cond   trt  ctrl
hour     0     3
E       10    10

我试过这 3 行:

subset(A, TRUE, select=(A[3:7,] > B[3:7,]))
subset(A, A > B)
A[A[3:7,] > B[3:7,]]

非常感谢。这是生成数据的代码:

A <- structure(list(name1 = c("trt", "0", "1", "10", "1", "1", "10"
), name2 = c("ctrl", "3", "1", "1", "1", "1", "10")), .Names = c("name1", 
"name2"), row.names = c("cond", "hour", "A", "B", "C", "D", "E"
), class = "data.frame")
B <- structure(list(name1 = c("trt", "0", "1", "1", "1", "1", "1"), 
    name2 = c("ctrl", "3", "1", "10", "1", "1", "1")), .Names = c("name1", 
"name2"), row.names = c("cond", "hour", "A", "B", "C", "D", "E"
), class = "data.frame")
############# 2/28/13 提出后续问题

Error when subsetting based on adjusted values of different data frame in R

【问题讨论】:

  • “小时”行值不大于。是否要忽略该行?
  • 是的,我想忽略小时和条件类别

标签: r dataframe


【解决方案1】:
N <- nrow(A)
cond <- sapply(3:N, function(i) sum(A[i,] > B[i,])==2)
rbind(A[1:2,], subset(A[3:N,], cond))

【讨论】:

  • 这很好。我看到您正在包含一个应用于这些值的函数。但我对 i? sapply 是否使用循环或其他东西?我真正喜欢的是,如果我希望 A 中 50% 的值大于 B,我现在可以将 sum==2 更改为 1。
  • 注意方:sum的使用很好,但是有点小技巧。如果您有像 A.name1 > A.name2 和 A.name1 B.name2 这样的条件怎么办?
  • 非常真实的 agstudy。这实际上是我打算这样做的地方。速度似乎还可以,使用我的真实数据集,redmode 花了 20 秒。但是,当您添加更多逻辑时,您的问题是正确的。
  • 当我执行sum(A[i,] &gt; 0.95*B[i,])==2 之类的操作时,我收到错误Error in FUN(left, right) : non-numeric argument to binary operator。我怎样才能使 A 中的值大于 B 的 95%?
  • @chimpsarehungry: sapply 是 loop-like 运算符,它将值从 3 传递到 N 到匿名函数,该函数返回一个逻辑值。所有返回值都组合在数组中。 i 是匿名函数的形式参数,每次它保存传递给函数的值(从3 到N)。
【解决方案2】:

我认为最好使用 SQL 进行这种表间过滤。它干净易读(您保留规则逻辑)。

 library(sqldf)
sqldf('SELECT DISTINCT A.*
        FROM A,B
        WHERE A.name1   > B.name1
        AND    A.name2  > B.name2')
  name1 name2
1   trt  ctrl
2    10    10

【讨论】:

  • “干净易读”?你到底是什么软件高手? :-)
  • @CarlWitthoft 对不起我的英语。我的意思是,该解决方案不会像在其他 2 个解决方案中使用 sum 或 prod 那样隐藏原始条件。我认为这也比 sapply 快(可能比具有相同逻辑的 data.table 解决方案慢)。无论如何,我是一名 .net 程序员,这些天如何尝试学习 R。(我不确定是否能很好地理解“软件运动员”)。
  • 他只是在开玩笑,说你的解决方案太人类可读了。不过我喜欢。我必须得到那个图书馆。
  • @CarlWitthoft oups !谢谢。我不能同时学习 R 和“英语二级笑话”:)
  • @agstudy 没有冒犯。事实上,我想你启发了我去看看sqldf
【解决方案3】:

必要的data.table解决方案:

library(data.table)

# just to preserve the order, non-alphabetically
idsA <- factor(rownames(A), levels=rownames(A))
idsB <- factor(rownames(B), levels=rownames(B))

# convert to data.table with id
ADT <- data.table(id=idsA, A, key="id")
BDT <- data.table(id=idsB, B, key="id")

# filter as needed
ADT[BDT][name1 > name1.1 & name2 > name2.1, list(id, name1, name2)]

【讨论】:

  • 我喜欢得到如此多样的解决方案。谢谢里卡多
  • 有没有办法使过滤部分不依赖于列名。只需根据 A 和 B 中各列的位置进行过滤。
  • 是的,您可以像处理 data.frame 一样进行过滤,但最后添加 , with=FALSE]
【解决方案4】:

如果我将你的矩阵重命名为 amat 和 bmat,那么

amat[which(sapply(1:nrows(amat),function(x) prod(amat[x,]>bmat[x,]))==1),]
[1] 10 10

如果需要,您可以重新粘贴“小时”行。

【讨论】:

  • 这与@redmode 所做的基本相同,所以我认为自己是及时的忍者,而不是混淆。
  • 你把我的字母卡尔弄丢了。
猜你喜欢
  • 1970-01-01
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-06
相关资源
最近更新 更多