避免参数重复通过(...)

时间:2011-12-20 19:49:08

标签: r

我有一个功能

somefun <- function(someparameters , ...) { plot(stuff, ...)}

现在我想在用户未指定这些参数的情况下为绘图提供一些默认值。 (即xlab="")。

如何提供一组默认的绘图选项,但仍允许用户覆盖这些参数?因为如果两次输入相同的参数,R将抛出错误:形式参数与多个实际参数匹配。

我知道我可以通过我的功能传递所有这些选项

somefun <- function(someparameters, main, xlab, ylab, xlim....)

但我宁愿不这样做。

是否有一些简单易用的解决方案来实现这一目标?

2 个答案:

答案 0 :(得分:19)

尝试modifyList使用如下:

f <- function(x, ...) {
    defaults <- list(xlab = "x", ylab = "y")
    args <- modifyList(defaults, list(x = x, ...))
    do.call("plot", args)
}

答案 1 :(得分:0)

可以考虑使用rlang中的list2函数

package stackoverflow.answers.demo;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Main extends Application {

    //Global Variables
    private static final int widthPane = 1000;
    private static final int heightPane = 650;
    long lastUpdateTime = 0;

    //canvas
    private Pane root = new Pane();

    //Enemy
    double bubbleAccelerationY = 300;
    double bubbleSpeedY = 30;
    double bubbleVelocityY = bubbleSpeedY;
    final int bubbleSpeedX = 200;
    int bubbleVelocityX = 0;
    int radiusBubble = 25;
    boolean moveDown = true;
    boolean moveRight = true;
    int maxHeight = 50;
    private Circle bubble = new Circle(radiusBubble, Color.CADETBLUE);

    private Parent createContent() {
        root.setPrefSize(widthPane, heightPane);
        root.getChildren().addAll(bubble);
        return root;
    }

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {

        bubble.setTranslateY(maxHeight);
        bubble.setTranslateX((int) (Math.random() * widthPane));

        Scene scene = new Scene(createContent());

        final AnimationTimer gameAnimation = new AnimationTimer() {
            @Override
            public void handle(long timestamp) {
                update(timestamp);
            }
        };
        gameAnimation.start();

        stage.setScene(scene);
        stage.show();
    }

    /**
     * changes velocity so that the bubble goes to the right
     */
    void moveBubbleRight() {
        bubbleVelocityX = bubbleSpeedX;
    }

    /**
     * changes velocity so that the bubble goes to the left
     */
    void moveBubbleLeft() {
        bubbleVelocityX = -bubbleSpeedX;
    }

    void accelerateBubble(double secs) {
        bubbleVelocityY += (secs * bubbleAccelerationY);
    }

    void bounceBubble() {
        bubbleVelocityY = -bubbleVelocityY;
    }

    /**
     * updates the pos of the bubble depending on the velocity, looks if it's about to leave the border, and sets it on
     * the edge if it is
     *
     * @param timestamp helps calculate the time that has passed since the last update / frame
     */
    private void update(long timestamp) {
        if (lastUpdateTime > 0) {

            final double elapsedSeconds = (timestamp - lastUpdateTime) / 1_000_000_000.0;

            //bubble
            //calculates YPos of bubble
            //changes which method should be called, if the ball has left the border
            //and sets him on the edge of it
            if (bubble.getTranslateY() >= heightPane - radiusBubble) {
                bubble.setTranslateY(heightPane - radiusBubble);
                bounceBubble();
            } else if (bubble.getTranslateY() <= maxHeight) {
                bubble.setTranslateY(maxHeight);
            }

            accelerateBubble(elapsedSeconds);

            final double deltaYBubble = elapsedSeconds * bubbleVelocityY;
            bubble.setTranslateY(bubble.getTranslateY() + deltaYBubble);

            //calculates XPos of Bubble
            if (bubble.getTranslateX() >= widthPane - radiusBubble) {
                bubble.setTranslateX(widthPane - radiusBubble);
                moveRight = false;
            } else if (bubble.getTranslateX() - radiusBubble <= 0) {
                moveRight = true;
            }

            if (moveRight) {
                moveBubbleRight();
            } else {
                moveBubbleLeft();
            }

            final double deltaXBubble = elapsedSeconds * bubbleVelocityX;

            bubble.setTranslateX(bubble.getTranslateX() + deltaXBubble);

        }
        lastUpdateTime = timestamp;
    }
}

这将返回传递给 somefun 的参数列表。然后,您可以插入自己的逻辑来确定它是否存在以及接下来要做什么。

my_dots <- rlang::list2(...)