R / VBA - сортировка данных - PullRequest
0 голосов
/ 13 марта 2012

Я пытаюсь создать набор данных из исходного кадра данных (в коде R или Excel VBA) и пытаюсь создать другой столбец. Вот ситуация высокого уровня:

dfr <- data.frame(
    grp   = rep(c("X", "Y"), each = 4),
    id    = c("A", "B", "C", "D", "E", "A", "B", "F"),
    value = c(3, 7, 2, 4, 8, 9, 11, 2)
) 

Во втором столбце B является «лидером» обеих групп «X» и «Y», поскольку у него самые большие цифры. Таким образом, мне нужно соединить все наблюдения и другие наблюдения в соответствующих группах (X, Y) с этими лидерами. Например, пример вывода ниже того, что мне нужно:

X  B A 3
X  B C 2
X  B D 4
Y  B E 8
Y  B A 9
Y  B F 2

Число в самом дальнем столбце соответствует номеру ранее найденной точки данных.

Итак, мне нужна помощь в распределении данных между X и Y (для бесчисленных существующих групп строк) и впоследствии, сортировка их так, как мне нужно, и создание этого столбца, либо в R-коде, либо в VBA для Excel ( данные в формате CSV)

** Отказ от ответственности: Если это не очевидно, мое использование R очень ограничено - я использовал его в течение 4 месяцев в курсе прикладной эконометрики, и теперь я снова нуждаюсь в нем (спустя 9 месяцев), поэтому, пожалуйста, извините, если я выгляжу как новичок ... хотя я могу отлично проводить регрессии:)

* UPDATE Следуя кодексу Генри, я сейчас здесь.

data <- read.csv(file = "sort.csv", h=T)
attach(data)
sorted <- data[order(data$membernumber, -data$dailycirc),]
top <- function(df){ return(df[1,])}
moded <- unsplit(lapply(split(sorted, sorted$membernumber), top), unique(sorted$membernumber))[1:2]
names(moded) <- c("membernumber", "cnty")
merged <- merge(moded, data, by="membernumber")
merged[merged$cnty != merged$cnty, ]
summary(merged)

Это действительно дало мне некоторые результаты. Но я не вижу такого рода, просто сводная статистика таких вещей, как среднее / максимальное. Как мне на самом деле экспортировать это в CSV или электронную таблицу, чтобы я мог смотреть на нее как на таблицу?

Большое спасибо за вашу помощь.

Ответы [ 4 ]

1 голос
/ 13 марта 2012

Используя пакет plyr, попробуйте

ddply(dfr, .(grp), transform, id.max = id[which.max(value)])

Здесь много отдельных вопросов, но, похоже, вам нужно несколько указателей, чтобы начать работать с R.

data <- read.csv(file = "sort.csv", h=T)

Не используйте T для TRUE, однажды вы объявите переменную с именем T и сгенерируете труднодоступную ошибку. Я также хотел бы написать header вместо h, так как будет более очевидно, что код делает, когда вы вернетесь к нему через 9 месяцев.


attach(data)

Neve use attach. Это еще один прекрасный источник трудно выявлять ошибки. Используйте с вместо.


sorted <- data[order(data$membernumber, -data$dailycirc),]

... вот так

sorted <- data[with(data, order(membernumber, -dailycirc)), ]

top <- function(df){ return(df[1,])}

Функция head уже делает это.


moded <- unsplit(lapply(split(sorted, sorted$membernumber), top),   unique(sorted$membernumber))[1:2]

Здесь tapply или ddply. Что-то вроде

moded <- with(sorted, tapply(cnty, membernumber, head, n = 1))

(Отметьте эту строку. Поскольку я не могу воспроизвести ваш пример, трудно сказать точно, каким он должен быть.)


merged[merged$cnty != merged$cnty, ]

Поскольку условие всегда FALSE, это должно вернуть пустой фрейм данных. Вы уверены, что имели в виду это?


Используйте write.csv или writeLines для записи файлов в файл.

1 голос
/ 13 марта 2012

следующие

sorted <- dfr[order(dfr$grp, -dfr$value), ]  
top <- function(df){ return(df[1,]) }
moded <- unsplit(lapply(split(sorted, sorted$grp), top), unique(sorted$grp))[1:2]
names(moded) <- c("grp", "leader")
merged <- merge(moded, dfr, by="grp")
merged[merged$leader != merged$id, ]

производит

  grp leader id value
1   X      B  A     3
3   X      B  C     2
4   X      B  D     4
5   Y      B  E     8
6   Y      B  A     9
8   Y      B  F     2

и

> summary(merged)
 grp   leader id        value      
 X:4   A:0    A:2   Min.   : 2.00  
 Y:4   B:8    B:2   1st Qu.: 2.75  
       C:0    C:1   Median : 5.50  
       D:0    D:1   Mean   : 5.75  
       E:0    E:1   3rd Qu.: 8.25  
       F:0    F:1   Max.   :11.00  
0 голосов
/ 13 марта 2012

Поскольку, похоже, проснулись только R люди, я чувствовал себя обязанным опубликовать пример в VBA. Я предполагаю, что вы открыли CSV в Excel с информацией в первых 3 столбцах, без заголовка (данные начинаются со строки 1). Вы копируете это данные в новую электронную таблицу, на вкладке с именем «Лист1». Вы вставляете приведенный ниже код в новый модуль и запускаете его, и он выводит результат в столбцах с 5 по 8 того же листа. При вводе 10000 строк он работает менее чем за 0,1 с на моем компьютере.

Option Explicit

Public Sub doIt()

    Dim data As Variant
    Dim result As Variant
    Dim i As Long
    Dim j As Long
    Dim dict1 As Variant
    Dim dict2 As Variant

    Set dict1 = CreateObject("Scripting.Dictionary")
    Set dict2 = CreateObject("Scripting.Dictionary")
    data = Sheets("Sheet1").UsedRange

    For i = LBound(data, 1) To UBound(data, 1)
        If dict1.exists(data(i, 1)) Then
            If dict2(data(i, 1)) < data(i, 3) Then
                dict1(data(i, 1)) = data(i, 2)
                dict2(data(i, 1)) = data(i, 3)
            End If
        Else
            dict1(data(i, 1)) = data(i, 2)
            dict2(data(i, 1)) = data(i, 3)
        End If
    Next i

    ReDim result(LBound(data, 1) To UBound(data, 1) - dict1.Count, 1 To 4) As Variant

    j = 1
    For i = LBound(data, 1) To UBound(data, 1)
        If data(i, 2) <> dict1(data(i, 1)) Then
            result(j, 1) = data(i, 1)
            result(j, 2) = dict1(data(i, 1))
            result(j, 3) = data(i, 2)
            result(j, 4) = data(i, 3)
            j = j + 1
        End If
    Next i

    With Sheets("Sheet1")
        .Cells(1, 5).Resize(UBound(result, 1), UBound(result, 2)) = result
    End With

End Sub
0 голосов
/ 13 марта 2012

Это, вероятно, не лучшее решение, и кто-то, вероятно, предложит вам лучшее решение, используя пакет reshape, но, похоже, оно работает для вашего примера и нескольких других, которые я пробовал.

df = data.frame(c(sample(c(LETTERS), 10000,replace=T)),
                sample(LETTERS[1:5],10000,replace=T),
                runif(10000))
names(df) = c("id","grp", "value")
i = levels(df$id)[1]

groupings =  lapply(levels(df$i), function(i){
                                    d = subset(df,df$id==i)
                                    l = length(d$value[d$id==i])
                                    m = max(d$value)
                                    leader= d$grp[d$value==m]
                                    piece = data.frame(id = rep(i,l),
                                                       grp= rep(as.character(leader),l),
                                                       grp2 = d$grp,
                                                       value = d$value)

                                    })

df.final = do.call(rbind,groupings)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...