使用Dplyr过滤3个以上级别的因素时出现错误消息

时间:2018-09-27 09:22:11

标签: r

我正在尝试过滤Dplyer中的某些因素,但是与其手动写出我想要的c(“ Blue”,“ Green”,“ White”)等,我想到了类似

package com.arena.game; import java.util.*; import java.util.concurrent.TimeUnit; public class Game { public static void foodSpawn(int diff, int w, int h, Window W) { while(true) { W.newFood(new food(diff,w,h)); try {TimeUnit.MILLISECONDS.sleep(20000);} catch (InterruptedException e) {e.printStackTrace();} } } public static void main(String[] args) { Random ran = new Random(); int width = 300; int height = 300; int diff = 1; int squareS = 100; int x = width/2-squareS/2; int y = height/2-squareS/2; int velx = ran.nextInt(15)+1; int vely = ran.nextInt(15)+1; Enemy f = new Enemy(squareS); Window win = new Window(width,height,f); foodSpawn(diff,width,height,win); while(true) { if (x >= width-squareS || x<=0) {velx=-velx; diff++; velx++; x=x+velx;} else {x=x+velx;} if (y >= height-squareS || y<=0) {vely=-vely; diff++; vely++; y=y+vely;} else {y=y+vely;} f.newxy(x,y); width = Window.newW(); height = Window.newH(); } } } package com.arena.game; import java.awt.*; import java.awt.event.*; import javax.swing.JFrame; public class Window extends JFrame{ int x = 0; int y = 0; public static int getW; public static int getH; public void newFood(food f) { super.add(f); } public Window(int width,int height,Enemy f) { getW = width; getH = height; super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); super.add(f); super.setSize(width, height); super.setVisible(true); super.getContentPane().addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { Component c = (Component)e.getSource(); int W = c.getWidth(); int H = c.getHeight(); getW = W; getH = H; } }); } public static int newW() { return getW; } public static int newH() { return getH; } } package com.arena.game; import java.awt.*; import javax.swing.*; import java.util.concurrent.TimeUnit; public class Enemy extends JPanel{ int x; int y; int SquareS; public Enemy(int SquareS) { this.SquareS = SquareS; } public void newxy(int x,int y) { this.x = x; this.y = y; try {TimeUnit.MILLISECONDS.sleep(100);} catch (InterruptedException e) {e.printStackTrace();} paintComponent(this.getGraphics()); } public void paintComponent(Graphics g) { super.paintComponent(g); this.setBackground(Color.BLUE); g.setColor(Color.RED); g.fillRect(x, y, SquareS, SquareS); } } package com.arena.game; import java.awt.*; import javax.swing.*; import java.util.*; import java.util.concurrent.TimeUnit; public class food extends JPanel{ Random ran = new Random(); int x; int y; public void paintComponent(Graphics g ,int Score) { super.paintComponent(g); // ERROR LINE g.setColor(Color.GREEN); g.fillRect(x, y, Score, Score); } public food(int Difficulty,int Wid,int Hei) { int Score = ran.nextInt(ran.nextInt(Difficulty)+1); x = ran.nextInt(Wid)+1; y = ran.nextInt(Hei)+1; try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace();y } paintComponent(this.getGraphics(),Score); } }

可能会证明速度更快,但是如果尝试使用以下代码选择两个以上的变量,则会收到错误消息 “较长的对象长度不是较短的对象长度的倍数” ,并且大部分数据都不会通过。在下面的虚拟数据中,2/3的数据消失了。

levels(df$factor.variable)[1:3]

请注意,如果仅选择以上级别的1或2(如[1]或[1:2],而不是[1:3]),则不会出现此问题。另外,如果我删除一种颜色(因素),那么我就不再有问题了。

a <- 1:20
b <- rep(c("Blue", "Green", "White", "Grey"),5)
df <- data.frame(Numbers=a, colours=b)
df %>% 
  select(Numbers, colours) %>% 
  filter(colours==levels(df$colours)[1:3])

哪些对象的长度更长或更短?为什么2/3的数据消失了?

2 个答案:

答案 0 :(得分:0)

您在dplyr中犯了错误。代替==使用%in%解决了该错误。

a <- 1:20
b <- rep(c("Blue", "Green", "White", "Grey"),5)
df <- data.frame(Numbers=a, colours=b)
str(df)

df2<- df %>% 
  select(Numbers, colours) %>% 
  filter(colours %in% levels(df$colours)[1:3])

答案 1 :(得分:0)

实际上不是dplyr问题。

正如其他人所述,a == b检查每对元素是否相同,即a[1] == b[1]a[2] == b[2],依此类推。 (请看?Comparison。)您正在比较长度不相等的向量,以及长度不适合于循环使用一个向量以适合另一个向量的向量,这就是发出警告的原因。

相反,a %in% b检查a中的每个元素是否存在于b中,并为a中的每个元素返回true或false。

为了说明您的数据:

library(dplyr)

a <- 1:20
b <- rep(c("Blue", "Green", "White", "Grey"),5)
df <- data.frame(Numbers=a, colours=b)

a %in% b表示中,这是您的b

levels(df$colours)[1:3]
#> [1] "Blue"  "Green" "Grey"

检查colours中每个元素是否在该值集中会产生逻辑矢量:

df$colours %in% levels(df$colours)[1:3]
#>  [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE
#> [12]  TRUE  TRUE  TRUE FALSE  TRUE  TRUE  TRUE FALSE  TRUE

dplyr::filter的基本R版本是这样的,它采用先前操作产生df$colours的{​​{1}}元素:

TRUE

df$colours[df$colours %in% levels(df$colours)[1:3]] #> [1] Blue Green Grey Blue Green Grey Blue Green Grey Blue Green #> [12] Grey Blue Green Grey #> Levels: Blue Green Grey White 中,非标准评估降低了对dplyr的需求,但是您在df$中所做的事情基本上是相同的:查找是否dplyr::filter的每个元素位于值colours的子集中,然后仅过滤与levels(colours)[1:3]对应的那些行。

TRUE