【问题标题】:Weird behaviour by ordering a data frame通过排序数据框的奇怪行为
【发布时间】:2013-01-09 09:33:37
【问题描述】:

我有以下数据框,我想按第五列(“距离”)排序。 当我尝试`

df.order <- df[order(df[, 5]), ]

我总是收到以下错误消息。

Error in order(df[, 5]) : unimplemented type 'list' in 'orderVector1'`

我不知道为什么 R 将我的数据框视为一个列表。运行 is.data.frame(df) 返回 TRUE。我不得不承认is.list(df) 也返回TRUE。是否可以强制我的数据框只是一个数据框而不是列表? 感谢您的帮助。

structure(list(ID = list(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 
               Latitude = list(50.7368, 50.7368, 50.7368, 50.7369, 50.7369, 50.737, 50.737, 50.7371, 50.7371, 50.7371), 
               Longitude = list(6.0873, 6.0873, 6.0873, 6.0872, 6.0872, 6.0872, 6.0872, 6.0872, 6.0872, 6.0872), 
               Elevation = list(269.26, 268.99, 268.73, 268.69, 268.14, 267.87, 267.61, 267.31, 267.21, 267.02), 
               Distance = list(119.4396, 119.4396, 119.4396, 121.199, 121.199, 117.5658, 117.5658, 114.9003, 114.9003, 114.9003), 
               RxPower = list(-52.6695443922406, -52.269130891243, -52.9735258244422, -52.2116571930007, -51.7784534281727, -52.7703448813654, -51.6558862949081, -52.2892907635308, -51.8322993596551, -52.4971436682333)), 
          .Names = c("ID", "Latitude", "Longitude", "Elevation", "Distance", "RxPower"),
          row.names = c(NA, 10L), class = "data.frame")

【问题讨论】:

  • 你做了什么来创建这样一个data.frame?这很不寻常。
  • @Roland 我使用另一个函数创建了数据框,该函数使用 lapply 将单列输出为列表以避免 for 循环。也许我应该用 sapply 来解决它。
  • 不,你应该在lapply 输出中使用do.call(cbind,...) 或类似的东西。
  • @Roland 哇。真是个好主意。

标签: r dataframe


【解决方案1】:

您的数据框包含列表,而不是向量。您可以使用as.data.frameunlist 将此数据框转换为“经典”格式:

df2 <- as.data.frame(lapply(df, unlist))

现在,可以按预期方式对新数据框进行排序:

df2[order(df2[, 5]), ]

【讨论】:

  • 像魅力一样工作。谢谢。
  • thought向量和列表是一样的
  • @AugustinRiedinger 从技术上讲,它们并不相同。列表是一种特殊类型的向量。通常,术语“向量”是指原子向量,即“逻辑”、“整数”、“数字”、“复数”、“字符”或“原始”模式的向量。
  • 向量也将数据强制转换为通用类型(即,如果您有数字和字符元素,则所有内容都将是字符)。 list 将保持类型正确,因此您要远离向量。
【解决方案2】:

我用一个小例子说明了问题所在:

df <- structure(list(ID = c(1, 2, 3, 4), 
          Latitude = c(50.7368, 50.7368, 50.7368, 50.7369), 
          Longitude = c(6.0873, 6.0873, 6.0873, 6.0872), 
          Elevation = c(269.26, 268.99, 268.73, 268.69), 
          Distance = c(119.4396, 119.4396, 119.4396, 121.199), 
          RxPower = c(-52.6695443922406, -52.269130891243, -52.9735258244422, 
                         -52.2116571930007)), 
          .Names = c("ID", "Latitude", "Longitude", "Elevation", "Distance", "RxPower"), 
          row.names = c(NA, 4L), class = "data.frame")

注意list 只出现一次。并且所有值都由c(.) 而不是list(.) 包装。这就是为什么对您的数据执行sapply(df, class) 会导致所有列都具有list 类。

现在,

> sapply(df, classs)
#       ID  Latitude Longitude Elevation  Distance   RxPower 
# "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" 

现在order 工作:

> df[order(df[,4]), ]  
#   ID Latitude Longitude Elevation Distance   RxPower
# 4  4  50.7369    6.0872    268.69 121.1990 -52.21166
# 3  3  50.7368    6.0873    268.73 119.4396 -52.97353
# 2  2  50.7368    6.0873    268.99 119.4396 -52.26913
# 1  1  50.7368    6.0873    269.26 119.4396 -52.66954

【讨论】:

  • 你说得对。我应该将我的数据框的所有列转换为向量而不是列表。谢谢。
【解决方案3】:

这会将列表的 data.frame 转换为矩阵:

mat <- sapply(df,unlist)

现在你可以订购了。

mat[order(mat[,5]),]

如果所有列都是一种类型,例如数字,则矩阵通常更可取,因为对矩阵的操作比对 data.frames 的操作要快。但是,您可以使用 as.data.frame(mat) 转换为 data.frame。

顺便说一句,data.frame 是一种特殊的列表,因此 is.list 为每个 data.frame 返回 TRUE

【讨论】:

  • 矩阵的好主意。谢谢。
【解决方案4】:

遇到了同样的问题。这对我有用(也许它可能会帮助遇到同样问题并偶然发现此页面的其他人)。

我的结构如下:

lst <- list(row1 = list(col1="A",col2=1,col3="!"), row2 = list(col1="B",col2=2,col3="@"))
> lst
$row1
$row1$col1
[1] "A"

$row1$col2
[1] 1

$row1$col3
[1] "!"


$row2
$row2$col1
[1] "B"

$row2$col2
[1] 2

$row2$col3
[1] "@"

我在做:

df <- as.data.frame(do.call(rbind, lst))

当我尝试df[order(df$col1),] 时,我一直收到与您相同的错误。原来我必须这样做:

df <- do.call(rbind.data.frame, lst)

【讨论】:

    猜你喜欢
    • 2011-03-13
    • 2012-12-17
    • 2011-03-06
    • 1970-01-01
    • 2015-04-20
    • 2011-02-17
    • 2019-01-18
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多