R - 对每个变量进行排序,在输出df中存储id和value列

时间:2017-05-17 16:53:46

标签: r loops sorting

我有一个大约80x300的数据框,这意味着它非常大,需要高效完成。以下示例。

id <- c("Alpha", "Bravo", "Charlie", Delta")
var1 <- c(1, 6, 4, 9)
var2 <- c(57, 49, 88, 14)
var3 <- c(11, 67, 2, 44)
df <- data.frame(id, var1, var2, var3)

我想最终得到一个单独的数据框,它按每个变量对这些数据进行排序,并存储id列和值变量列。它看起来像这样:

var1.n     var1.v     var2.n     var2.v     ...
Delta      9          Charlie    88
Bravo      6          Alpha      57
Charlie    4          Bravo      49
Alpha      1          Delta      14
...

此前的尝试不包括值变量(仅名称变量),并且使用此方法

完成
out <- as.data.frame(apply(df[,-1], 2, function(x) df$id[order(-x)]))

但是我无法弄清楚如何扩展它以包含id列和值变量。我尝试了下面的两种方法,但是1)无法让代码正常运行,因为它使用了一些我并不完全熟悉的命令,2)无法弄清楚如何实现我头脑中的确切内容。第一个尝试通过在每个点注入一列NA来在原始数据框架中工作,但我很快发现这不起作用。第二个是尝试创建一个新的输出框架,在其中我按第i列排序,然后存储id变量,然后存储看起来很有希望的第i列,但我必须丢失一些东西因为它没有做任何事情或给出像更换错误的东西。

# attempt 1
for (i in 1:ncol(df)) {
  df<- as.data.frame(append(df, list(paste(colnames(df)[i],"name", sep="_")=NA), after=i))
  df<- order(df[i]) # would need to skip alternating rows
  df[i] <- df$id # not right at all
}

# attempt two
for (i in 1:ncol(df)) {
  order(df[i])
  out$paste(colnames(df)[i],"name", sep="_")] <- df$id
  out$paste(colnames(df)[i]) <- df[i]
}

这有一些额外的细微差别,所以如果可能的话,我会喜欢一种可推广的方法,但我会尽我所能得到所有的帮助。

3 个答案:

答案 0 :(得分:1)

这样的事情怎么样?

    package com.sundogsoftware.sparkstreaming

    import java.util
    import java.util.Properties
    import org.apache.kafka.clients.consumer.KafkaConsumer
    import scala.collection.JavaConverters._
    import org.apache.kafka.clients.consumer.{ ConsumerRecords, KafkaConsumer }
    import org.apache.kafka.clients.producer.{ KafkaProducer, Producer, ProducerConfig, ProducerRecord }
    import java.util.Arrays;


object ConsumerExample extends App {
  val props = new Properties()
  props.put("bootstrap.servers", "localhost:9092");
  props.put("group.id", "test-group");
  props.put("enable.auto.commit", "true");
  props.put("auto.commit.interval.ms", "1000");
  props.put("session.timeout.ms", "30000");
  props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
  props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
  props.put("partition.assignment.strategy", "range");

  val consumer = new KafkaConsumer[String, String](props)

  consumer.subscribe(Arrays.asList("kafkatopic"))

  while (true) {
    val records = consumer.poll(100)
    println(consumer)
    println(records)
    for (record <- records.asScala) {
      println(record)
    }
  }
}

答案 1 :(得分:1)

如果我没有弄错的话,你需要一个新的data.frame,其中包含已排序的变量,每个数据旁边都有一个单独的ID列。

我认为这就是你要找的东西(我是根据你自己的例子写的):

df2 <- data.frame(matrix(nrow = nrow(df), ncol = 0))
for(i in 2:ncol(df)) {
    newColName.n <- paste(colnames(df)[i], "n", sep = ".") # ID column for the current variable.
    newColName.v <- paste(colnames(df)[i], "v", sep = ".") # Sorted variable column in descending order.
    idx <- order(df[, i], decreasing = T)
    temp <- data.frame(v1 = df$id[idx], v2 = df[idx, i])
    colnames(temp) <- c(newColName.n, newColName.v)
    df2 <- cbind(df2, temp)
}

最后,df2就是你想要的。

答案 2 :(得分:0)

这可以通过lapply完成。

df1 <-  lapply(names(df[,-1]), function(x) {
    o <-  cbind(df[1], df[x])
   colnames(o) <- c(paste0(x, ".n"), paste0(x, ".v") )
    o <- o[order(-o[2]),]
 })
 df2 <- do.call(cbind, df1)