我需要使用 R *apply 函数为初学者制作教程(第一次不使用 reshape 或 plyr 包)
我尝试 lapply
(因为我读了 apply
对数据框不好)这个数据框的一个简单函数,我想使用命名列来访问数据:
fDist <- function(x1,x2,y1,y2) {
return (0.1*((x1 - x2)^2 + (y1-y2)^2)^0.5)
}
data <- read.table(textConnection("X1 Y1 X2 Y2
1 3.5 2.1 4.1 2.9
2 3.1 1.2 0.8 4.3
"))
data$dist <- lapply(data,function(df) {fDist(df$X1 , df$X2 , df$Y1 , df$Y2)})
我有这个错误
$ operator is invalid for atomic vectors
,这可能是因为数据框被 laply 修改了?...有没有最好的方法来用 $ 命名列来做到这一点?我用@DWin 回答解决了我的第一个问题。但我有另一个问题,误解,混合数据框(数字+字符):
在我的新用例中,我使用两个函数来计算距离,因为我的目标是比较所有其他 Point 之间的距离 Point。
data2 <- read.table(textConnection("X1 Y1 X2 Y2
1 3.5 2.1 4.1 2.9
2 3.1 1.2 0.8 4.3
"))
data2$char <- c("a","b")
fDist <- function(x1,y1,x2,y2) {
return (0.1*((x1 - x2)^2 + (y1-y2)^2)^0.5)
}
fDist2 <- function(fixedX,fixedY,vec) {
fDist(fixedX,fixedY,vec[['X2']],vec[['Y2']])
}
# works with data (dataframe without character), but not with data2 (dataframe with character)
#ok
data$f_dist <- apply(data, 1, function(df) {fDist2(data[1,]$X1,data[1,]$Y1,df)})
#not ok
data2$f_dist <- apply(data2, 1, function(df) {fDist2(data2[1,]$X1,data2[1,]$Y1,df)})
最佳答案
在这种情况下 apply
是你所需要的。所有数据列的类型都相同,您不必担心丢失属性,这就是 apply 导致问题的地方。您将需要以不同的方式编写您的函数,因此它只需要一个长度为 4 的向量:
fDist <- function(vec) {
return (0.1*((vec[1] - vec[2])^2 + (vec[3]-vec[4])^2)^0.5)
}
data$f_dist <- apply(data, 1, fDist)
data
X1 Y1 X2 Y2 f_dist
1 3.5 2.1 4.1 2.9 0.1843909
2 3.1 1.2 0.8 4.3 0.3982462
如果您想使用“数据”中列的名称,则需要正确拼写它们:
fDist <- function(vec) {
return (0.1*((vec['X1'] - vec['X2'])^2 + (vec['Y1']-vec['Y2'])^2)^0.5)
}
data$f_dist <- apply(data, 1, fDist)
data
#--------
X1 Y1 X2 Y2 f_dist
1 3.5 2.1 4.1 2.9 0.1000000
2 3.1 1.2 0.8 4.3 0.3860052
您更新的(和非常不同的)问题很容易解决。当您使用
apply
它强制转换为最低的共模分母,在本例中为“字符”。您有两种选择:1) 添加 as.numeric
到函数内的所有参数,或 2) 仅发送我将说明的所需列:data2$f_dist <- apply(data2[ , c("X2", "Y2") ], 1, function(coords)
{fDist2(data2[1,]$X1,data2[1,]$Y1, coords)} )
我真的不喜欢你向这个函数传递参数的方式。在正式列表中使用“[”和“$”“看起来是错误的”。而且您应该知道“df”不是数据帧,而是向量。因为它不是数据框(或列表),所以您应该更改内部的函数,使其使用“[”而不是“[[”。由于您只需要两个坐标,因此只需传递您将使用的两个(数字)坐标。
关于r - 使用 *apply 函数访问数据框的列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9624866/