【问题标题】:R use a character string to retrieve data columnR使用字符串检索数据列
【发布时间】:2016-04-16 12:05:28
【问题描述】:

我正在为看似简单的事情而苦苦挣扎;但我已经坚持了很长一段时间了。

我有一个很长的 data.frame,但这里有一个可以代表它的示例。

my.dataframe<-data.frame(PointA.X=sample(100,4))
my.dataframe$PointA.Y<-sample(100,4)
my.dataframe$PointB.X<-sample(100,4)
my.dataframe$PointB.Y<-sample(100,4)

     PointA.X PointA.Y PointB.X PointB.Y
1       93       98       46       45
2       58        3       80       89
3       61       64       17       14
4       56       46       65       23

我正在寻找一个函数,该函数将使用两个参数,从中会出现更多参数。

MyFunction<-function(Start, End){
XStart <- get(as.character(paste0("Mydataframe$" , Start , ".X")))
XEnd   <- get(as.character(paste0("Mydataframe$" , End   , ".X")))
YStart <- get(as.character(paste0("Mydataframe$" , Start , ".Y")))
YEnd   <- get(as.character(paste0("Mydataframe$" , End   , ".Y" )))
sqrt(((XStart - XEnd) ^ 2 + (YStart - YEnd) ^ 2))
} # End of My Function

在这种情况下,我将定义 StartPoint 和 EndPoint 来计算它们之间的线段长度。 MyFunction("PointA", "PointB")

据我了解

MyFunction("PointA", "PointB")

以下

as.character(paste0("Mydataframe$" , Start , ".X")) 

返回

"Mydataframe$PointA.X"

这是我的数据框中的有效列 使用 get() 是在寻找一个对象,而不是寻找实际的数据。

这就是我卡住的地方。是否有返回我正在寻找的值的功能?

提前谢谢大家

【问题讨论】:

  • 没错。 get() 寻找对象。 "Mydataframe$PointA.X" 不是对象。 Mydataframe 是一个对象,PointA.X 是该对象中的一列。但是"Mydataframe$PointA.X" 不是对象的名称,这是get() 想要的参数。 .但是你为什么要这样做呢?您可以使用Mydataframe[[paste0(Start, ".X")]]等。
  • 嗨,理查德,感谢您的回复。这是个好主意。我试图缩短我的代码,因为我有 100 列,我会计算它们的长度 2 乘 2 等等。

标签: r character data-retrieval


【解决方案1】:
Try this. It may help.


MyFunction<-function(Start, End){
XStart <- eval(parse(text=paste("my.dataframe$",Start,".X", sep = "")))
XEnd   <- eval(parse(text=paste("my.dataframe$",End,".X", sep = "")))
YStart <- eval(parse(text=paste("my.dataframe$",Start,".Y", sep = "")))
YEnd   <- eval(parse(text=paste("my.dataframe$",End,".Y", sep = "")))
sqrt(((XStart - XEnd) ^ 2 + (YStart - YEnd) ^ 2))
}

【讨论】:

    【解决方案2】:

    正如 Richard 所建议的,可以使用括号 [[]] 中的字符串对数据框进行子集化,但不能使用 $ 符号。

    所以对未来的建议:使用括号...

      MyFunction<-function(Start, End){
      XStart <- my.dataframe[[paste0(Start, ".X")]]
      YStart <- my.dataframe[[paste0(Start, ".Y")]]
    
      XEnd <- my.dataframe[[paste0(End, ".X")]]
      YEnd <- my.dataframe[[paste0(End, ".Y")]]
    
      sqrt(((XStart - XEnd) ^ 2 + (YStart - YEnd) ^ 2))
    } # End of My Function
    
    MyFunction("PointA", "PointB") # Note the arguments are provided as characters
    > [1] 39.20459 80.52950 34.17601  6.00000
    

    更有趣的是,我还可以在列名之间循环该函数。所以如果数据报更长。

    my.dataframe<-data.frame(PointA.X=sample(100,4))
    my.dataframe$PointA.Y<-sample(100,4)
    my.dataframe$PointB.X<-sample(100,4)
    my.dataframe$PointB.Y<-sample(100,4)
    my.dataframe$PointC.X<-sample(100,4)
    my.dataframe$PointC.Y<-sample(100,4)
    

    并且功能保持不变:

    MyFunction<-function(Start, End){
    XStart <- my.dataframe[[paste0(Start, ".X")]]
    YStart <- my.dataframe[[paste0(Start, ".Y")]]
    
    XEnd <- my.dataframe[[paste0(End, ".X")]]
    YEnd <- my.dataframe[[paste0(End, ".Y")]]
    
    sqrt(((XStart - XEnd) ^ 2 + (YStart - YEnd) ^ 2))
    } # End of My Function
    

    我可以构建一个 for 循环:

    for (VariableI in seq(from=1, to=length(colnames(my.dataframe)), by=2)){
    Start<-unlist(strsplit(colnames(my.dataframe)[VariableI], "[.]"))[1]
    End<-unlist(strsplit(colnames(my.dataframe)[VariableI+2], "[.]"))[1]
    assign(paste0(Start,End), MyFunction(Start, End)) 
    }
    

    创建以下对象

     PointAPointB
        [1] 32.57299 74.30343 73.08215 83.25863
        PointBPointC
        [1]  5.385165 90.609050 68.883960 58.137767
    

    我想我只是缺少 PointAPointC。 我可能会使用 combine 函数来绕过这个

     combn(colnames(my.dataframe), 2)
    
        [,1]       [,2]       [,3]       [,4]       [,5]       [,6]       [,7]       [,8]       [,9]       [,10]     
    [1,] "PointA.X" "PointA.X" "PointA.X" "PointA.X" "PointA.X" "PointA.Y" "PointA.Y" "PointA.Y" "PointA.Y" "PointB.X"
    [2,] "PointA.Y" "PointB.X" "PointB.Y" "PointC.X" "PointC.Y" "PointB.X" "PointB.Y" "PointC.X" "PointC.Y" "PointB.Y"
         [,11]      [,12]      [,13]      [,14]      [,15]     
    [1,] "PointB.X" "PointB.X" "PointB.Y" "PointB.Y" "PointC.X"
    [2,] "PointC.X" "PointC.Y" "PointC.X" "PointC.Y" "PointC.Y"
    

    【讨论】:

      猜你喜欢
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-23
      • 1970-01-01
      • 2017-07-27
      相关资源
      最近更新 更多