如何使用apply语句而不是for for循环执行此代码?

时间:2018-01-12 23:05:02

标签: r list dataframe ggplot2 apply

我有一个数据框列表,其中df中的每一列对应于来自相同长度的不同数字向量的函数值的评估。 每个列表对象(数据帧)都使用不同的函数生成

我想遍历每个列表对象(dataframe)   1.为每个列表对象(数据帧)生成一个绘图,列为数据系列。   2.生成新的数据框列表,其中包含原始数据框中每列均值的列

下面的代码是有用的,但有没有更好的方法来使用apply语句并避免for循环?

plots <- list()
trait.estimate <- list()

 for(i in 1:length(component.estimation)) {  #outter loop start
  component.estimation[[i]]$hr <- hr #add hr vector to end of dataframe 
  temporary.df <- melt(component.estimation[[i]] ,  id.vars = 'hr', variable.name = 'treatment')

 #Store a plot of each df
plots[[i]] <- ggplot(temporary.df, aes(hr , value), group = treatment, colour = treatment, fill = treatment) +
  geom_point(aes(colour = treatment, fill = treatment))+
  geom_line(aes(colour= treatment, linetype = treatment))+
  ggtitle( names(component.estimation)[i])+  #title to correspond to trait
  theme_classic()

  #Generate column averages for each df
trait.estimate[[i]] <- apply(component.estimation[[i]] ,2, mean)
trait.estimate[[i]] <- as.data.frame(trait.estimate[[i]])
trait.estimate[[i]]$treatment <- row.names(trait.estimate[[i]])
  } #outter loop close

1 个答案:

答案 0 :(得分:3)

您的 // Display the camera frame public Mat onCameraFrame(CvCameraViewFrame inputFrame) { // The object's width and height are set to 0 objectWidth = objectHeight = 0; // frame is captured as a coloured image frame = inputFrame.rgba(); /** Since the Canny algorithm only works on greyscale images and the captured image is * coloured, we transform the captured cam image into a greyscale one */ Imgproc.cvtColor(frame, grey, Imgproc.COLOR_RGB2GRAY); // Calculating borders of image using the Canny algorithm Imgproc.Canny(grey, canny, 180, 210); /** To avoid background noise (given by the camera) that makes the system too sensitive * small variations, the image is blurred to a small extent. Blurring is one of the * required steps before any image transformation because this eliminates small details * that are of no use. Blur is a low-pass filter. */ Imgproc.GaussianBlur(canny, canny, new Size(5, 5), 5); // Calculate the contours Imgproc.findContours(canny, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); /** The contours come in different sequences * 1 sequence for each connected component. * Taking the assumption only 1 object is in view, if we have more than 1 connected * component, this'll be considered part of the details of the object. * * For this, we put all contours together in a single sequence * If there is at least 1 contour, I can continue processing */ for (MatOfPoint mat : contours) { // Retrieve and store all contours in one giant map mat.copyTo(allContours); } MatOfPoint2f allCon = new MatOfPoint2f(allContours.toArray()); // Calculating the minimal rectangle to contain the contours RotatedRect box = Imgproc.minAreaRect(allCon); // Getting the vertices of the rectangle Point[] vertices = initialiseWithDefaultPointInstances(4); box.points(vertices); // Now the vertices are in possession, temporal smoothing can be performed. for (int i = 0; i < 4; i++) { // Smooth coordinate x of the vertex vertices[i].x = alpha * lastVertices[i].x + (1.0 - alpha) * vertices[i].x; // Smooth coordinate y of the vertex vertices[i].y = alpha * lastVertices[i].y + (1.0 - alpha) * vertices[i].y; // Assign the present smoothed values as lastVertices for the next smooth lastVertices[i] = vertices[i]; } /** With the vertices, the object size is calculated. * The object size is calculated through pythagoras theorm. In addition, it gives * the distance between 2 points in a bi-dimensional space. * * For a rectangle, considering any vertex V, its two sizes (width and height) can * be calculated by calculating the distance of V from the previous vertex and * calculating the distance of V from the next vertex. This is the reason why I * calculate the distance between vertici[0]/vertici[3] and vertici[0]/vertici[1] */ objectWidth = (int) (conversionFactor * Math.sqrt((vertices[0].x - vertices[3].x) * (vertices[0].x - vertices[3].x) + (vertices[0].y - vertices[3].y) * (vertices[0].y - vertices[3].y))); objectHeight = (int) (conversionFactor * Math.sqrt((vertices[0].x - vertices[1].x) * (vertices[0].x - vertices[1].x) + (vertices[0].y - vertices[1].y) * (vertices[0].y - vertices[1].y))); /** Draw the rectangle containing the contours. The line method draws a line from 1 * point to the next, and accepts only integer coordinates; for this reason, 2 * temporary Points have been created and why I used Math.round method. */ Point pt1 = new Point(); Point pt2 = new Point(); for (int i = 0; i < 4; i++) { pt1.x = Math.round(vertices[i].x); pt1.y = Math.round(vertices[i].y); pt2.x = Math.round(vertices[(i + 1) % 4].x); pt2.y = Math.round(vertices[(i + 1) % 4].y); Imgproc.line(frame, pt1, pt2, red, 3); } //If the width and height are non-zero, then print the object size on-screen if (objectWidth != 0 && objectHeight != 0) { String text; text = String.format("%d x %d", objectWidth, objectHeight); widthValue.setText(text); } // This function must return return frame; } // Initialising an array of points public static Point[] initialiseWithDefaultPointInstances(int length) { Point[] array = new Point[length]; for (int i = 0; i < length; i++) { array[i] = new Point(); } return array; } 循环对我来说很好,我不担心转换到for。就个人而言,我认为当你想要做一些简单的事情时lapply很棒,但是当你想要更复杂的东西时,for循环可以同样可读。

我唯一真正的改变是使用lapply而不是colMeans。我也可能将apply(., 2, mean)部分和绘图部分分开,因为它们看起来完全是分开的操作。组织上似乎更好。

例如,取出trait.estimate计算结果如下:

trait.estimate

哪个更好?我会留给你决定。使用您喜欢的任何一种。