如何在R中转动和居中坐标系

时间:2017-03-13 09:29:54

标签: r

真的很感谢这个帮助。我是编程新手,但坚持学习。我用R(工作室)。

我在离散的时间步长沿着细的弯曲线(miroorganism flagellum)有X和Y坐标。随着时间的推移,我基本上跟踪了鞭毛。数据如下所示:

切片X Y

750 180 178

750 189 172

750 X3 Y3

750 X4 Y4

751 X5 Y5

751 X6 Y6

751 X7 Y7

751 X8 Y8

752 X9 Y9

..... Xn Yn

第一列(切片)是时间步长,所以我有一个数字(但不总是相同的数字),每个时间步长的X,Y坐标。这是它的外观图像:

Data representation. Each line is defined by a number (10-15) discrete [X,Y] coordinates. The different lines are the different 'slices'.

现在,我想做几件事:

  1. 居中(将所有数据移动到)所有第一个[X,Y]坐标的平均值。也就是说,每次切片编号改变时,[X,Y]坐标的平均值。
  2. 按照每个“切片”的第一个和最后一个数据集之间的直线定义的平均角度旋转整个数据集,以便每个切片的第一个数据点从[0,0]和后续数据点开始在正X方向上围绕X轴波动。
  3. 虽然数据当然特定于我的情况,但是居中和转动坐标系统的问题肯定是更普遍的问题。我想我需要做一个for循环,但我仍然坚持根据'Slice'数字识别和提取[X,Y]坐标。

    我已将数据放在此处,以防有人有兴趣帮助:https://dl.dropboxusercontent.com/u/6791606/Flagellum%20track%200012%20100fps%20-%20converted.csv

    我真的希望你能帮助我。

2 个答案:

答案 0 :(得分:0)

也许是这样的:

编辑现在包括由Adi Sarid改变角度+ ggplot代码

import UIKit
import AVFoundation

var audioPlayer = AVAudioPlayer()

class ViewController: UIViewController {

@IBOutlet weak var slider: UISlider!
@IBOutlet weak var playButton: UIButton!
var index = 0
var timer: Timer?

override func viewDidLoad() {
    super.viewDidLoad()

    if index == 0{

       let url = Bundle.main.url(forResource: "1", withExtension: "mp3")!

        do {
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer.prepareToPlay()
            //audioPlayer.play()
            //play(sender:AnyObject.self as AnyObject)

        } catch let error {
            print(error.localizedDescription)
        }
    }
}

@IBAction func slide(_ slider: UISlider) {
    audioPlayer.currentTime = TimeInterval(slider.value)
}

@IBAction func play(sender: AnyObject) {
    if !audioPlayer.isPlaying{
        audioPlayer.play()
        // **** The line below is the new line ****
        timer = Timer(timeInterval: 1.0, target: self, selector: #selector(self.updateSlider), userInfo: nil, repeats: true)
        RunLoop.main.add(timer!, forMode: .commonModes)
    } else {
        audioPlayer.pause()
        playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
        timer?.invalidate()
    }
}

func updateSlider(_ timer: Timer) {
    slider.value = Float(audioPlayer.currentTime)
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}
}

我没有完全理解您的要求所以请告诉我这是否有效。此外,您可能需要添加模型来处理曲线

答案 1 :(得分:0)

这是一种优雅的方式来预先形成这个没有任何循环。 通常,尽可能避免在R中循环,您可以使用更高效的专用函数。 我建议掌握tidyr进行数据操作。

library(tidyr)
library(readr)
flag.rotation <- flag.centered %>%
                 group_by(Slice) %>%
                 summarize(f.x = first(X), f.y = first(Y),
                           l.x = last(X), l.y = last(Y)) %>%
                 mutate(rot.ang = atan((l.y-f.y)/(l.x-f.x))) %>%
                 select(rot.ang)

rotate.ang <- -mean(flag.rotation$rot.ang)

这为您提供了想要旋转的角度(在您的样本中,这大约是0.97弧度)。然后,要实际旋转数据,请使用:

flag.rotated <- flagellum %>%
                mutate(rot.X = cos(rotate.ang)*X - sin(rotate.ang)*Y,
                rot.Y = sin(rotate.ang)*X + cos(rotate.ang)*Y) %>%
                select(Slice, rot.X, rot.Y)

对于居中,首先找到中心:

flag.center <- flag.rotated %>%
               group_by(Slice) %>%
               mutate(f.rot.X = first(rot.X), f.rot.Y = first(rot.Y)) %>%
               select(Slice, f.rot.X, f.rot.Y) %>%
               unique() %>%
               ungroup() %>%
               select(f.rot.X, f.rot.Y) %>%
               summarize(mean.f.X = mean(f.rot.X), mean.f.Y = mean(f.rot.Y))

中心(已经旋转的数据)现在包含在flag.center中。现在我们可以使用它来对旋转的数据进行居中:

flag.centered <- flag.rotated %>%
                 mutate(X = rot.X - flag.center$mean.f.X, Y = rot.Y - flag.center$mean.f.Y) %>%
                 select(X, Y, Slice)

这导致以下图表(数据点的透明度为50%,线条为“黄土”平滑线): Updated flagella plot - rotated and centered 您可以使用ggplot2生成它:

# For producing the smoothed plot I used:
library(ggplot2)
ggplot(flag.centered, aes(x = X, y = Y)) + 
  geom_point(aes(color = factor(Slice)), alpha = 0.5) + 
  stat_smooth(aes(color = factor(Slice)), se = FALSE)