【问题标题】:How can I apply a piece of R code to every column of my data frame如何将一段 R 代码应用于我的数据框的每一列
【发布时间】:2021-08-22 17:34:16
【问题描述】:

我必须分析 EMG 数据,但我不太擅长使用 R: 我有一个包含 9 列的 data.frame:一列指定时间,另外 8 列指定我的频道。 我想过滤我的 emg 数据,但我只能按通道执行此操作,但我想一次对数据帧的所有通道执行此操作,因此我不必将其应用于每个通道。

# This example computes the LE-envelope using the lowpass routine

# Coerce a data.frame into an 'emg' object
x <- as.emg(extensor_raw$channel1, samplingrate = 1000, units = "mV")  ##do this for every channel

# Compute the rectified signal
x_rect <- rectification(x)

# Filter the rectified signal
y <- lowpass(x_rect, cutoff = 100)

# change graphical parameters to show multiple plots
op <- par(mfrow = c(3, 1))

# plot the original channel, the filtered channel and the 
# LE-envelope
plot(x, channel = 1, main = "Original  channel")
plot(x_rect, main = "Rectified  channel")
plot(y, main = "LE-envelope")

# reset graphical parameters
par(op)

所以我可以在这里放一些像 extensor_raw$i 这样的东西并围绕它循环,而不是在这里使用 extensor_raw$channel1 吗?或者有没有办法将这段代码应用于每个通道(即 9 列数据帧的 8 列,不包括指定时间的第一列?)

【问题讨论】:

    标签: r loops filter apply


    【解决方案1】:

    如果是按列,则使用lapply 并存储为list,并假设所有列都需要更改。 (请注意,这未经测试。plot 中的par 可能需要更改)

    lst1 <- lapply(extensor_raw, \(vec) {
          x <- as.emg(vec, samplingrate = 1000, units = "mV")  
    
          # Compute the rectified signal
           x_rect <- rectification(x)
         # Filter the rectified signal
         y <- lowpass(x_rect, cutoff = 100)
    
         # change graphical parameters to show multiple plots
         op <- par(mfrow = c(3, 1))
    
         # plot the original channel, the filtered channel and the 
        # LE-envelope
         plot(x, channel = 1, main = "Original  channel")
        plot(x_rect, main = "Rectified  channel")
         plot(y, main = "LE-envelope")
    
    
    # reset graphical parameters
    par(op)
    })
    

    【讨论】:

      【解决方案2】:

      这是我的解决方案。首先,由于您的问题没有数据,我使用了 UCI 机器学习存储库中的“用于手势数据集的 EMG 数据”。

      链接https://archive.ics.uci.edu/ml/datasets/EMG+data+for+gestures

      你使用的数据集非常相似,第一个变量是时间,之后 8 个变量是通道,最后一个是类

      要为每个通道创建图表,您可以使用 FOR 循环,将您关注的列用作迭代运算符。中间代码和你的一样,最后在绘图时我对绘图标题进行了更改,使其与各自的列名相似。

      library(biosignalEMG)
      
      extensor_raw <- read.delim("01/1_raw_data_13-12_22.03.16.txt")
      head(extensor_raw)
      
      for(i in names(extensor_raw[2:9])){
        print(paste("Drawing for ", i))
        # Coerce a data.frame into an 'emg' object
        x <- as.emg(extensor_raw[i], samplingrate = 1000, units = "mV")  ##do this for every channel
        
        # Compute the rectified signal
        x_rect <- rectification(x)
        
        # Filter the rectified signal
        y <- lowpass(x_rect, cutoff = 100)
        
        # change graphical parameters to show multiple plots
        op <- par(mfrow = c(3, 1))
        
        # plot the original channel, the filtered channel and the 
        # LE-envelope
        plot(x, channel = 1, main = paste("Original ", i))
        plot(x_rect, main = paste("Rectified", i))
        plot(y, main = paste("LE-envelope", i))
        
      }
      

      在这段代码的末尾,您可以看到在 rstudio 的图形部分中创建了多个页面,同时绘制从 1 到 8 的每个通道

      喜欢第 5 频道,也喜欢其他频道。我希望这能帮助您解决问题。

      关于您在 cmets 中询问的第二部分:如果您将文件分开,让我们将其分开。将一一阅读,然后绘制它。为此,我们将使用嵌套的 FOR 循环。 首先设置您的工作目录,其中包含所有手势文件。就像我的情况一样,我的目录中有两个具有相同结构的文件。

      代码改动如下:

      setwd('~/Downloads/EMG_data_for_gestures-master/01')
      library(biosignalEMG)
      
      for(j in list.files()){
        print(paste("reading file ",j))
        extensor_raw <- read.delim(j)
        head(extensor_raw)
        
        for(i in names(extensor_raw[2:9])){
          print(paste("Drawing for ", i))
          # Coerce a data.frame into an 'emg' object
          x <- as.emg(extensor_raw[i], samplingrate = 1000, units = "mV")  ##do this for every channel
          
          # Compute the rectified signal
          x_rect <- rectification(x)
          
          # Filter the rectified signal
          y <- lowpass(x_rect, cutoff = 100)
          
          # change graphical parameters to show multiple plots
          op <- par(mfrow = c(3, 1))
          
          # plot the original channel, the filtered channel and the LE-envelope
          
          plot(x, channel = 1, main = paste("Original ", i," from ", j))
          plot(x_rect, main = paste("Rectified", i," from ", j))
          plot(y, main = paste("LE-envelope", i," from ", j))
          
        }
      }
      

      我希望这会有所帮助。

      【讨论】:

      • 非常感谢您的快速答复!它奏效了,对我很有帮助!我的数据框实际上不包括第 10 列“类”,因为我们已经在单个 csv 中记录了所有手势。文件。 (所以我们有一个用于伸肌、屈肌、拳头、张开手等的文件......)但我有一个关于此的后续问题:如果我将我的 8 个手势文件绑定在一起,以便我得到一个类似的数据框您使用过,包括所有 8 个手势:我将如何绘制为每个手势分开的每个通道(如上所示)?最好的问候,Cel。
      • 嗨 Cel,我已将您在 cmets 中提出的问题的答案添加到我上面的原始答案中,方法是在其中附加新代码。请检查,我想它会解决你的问题。如果它对您有用,请点赞,这样它也将造福于他人
      • 非常感谢您的快速响应和出色的解释!它工作得很好。我想投票,但我害怕,因为我是这里的新手,所以我还没有达到这样做的声誉。我收到消息:“感谢您的反馈!您需要至少 15 个声望才能投票,但您的反馈已被记录。”但我希望我能尽快达到声誉投赞成票!最好的问候!
      • 谢谢 cel :) !!
      • 你好 Anup:我实际上对我的第一个问题有一个后续问题:是否可以将我现在为通道获得的所有图整合到一个图中,明显地用颜色分隔?:我有还在单独的帖子stackoverflow.com/questions/67848482/… 中发布了这个问题,但由于它与此有关,我想我会再次在这里提问。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2021-12-22
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多