Как добавить счетный столбец на основе значений в других столбцах в R - PullRequest
5 голосов
/ 18 декабря 2011

У меня относительно большой набор данных (16000+ x ~ 31). Другими словами, он достаточно большой, поэтому я не хочу манипулировать им построчно в Excel. Данные в этой форме:

block  site     day  X1   X2
1      1        1    0.4  5.1 
1      1        2    0.8  1.1
1      1        3    1.1  4.2
1      2        1    ...  ...
1      2        2
1      2        3
2      3        1
2      3        2
2      3        3
2      4        1
2      4        2
2      4        3

Как видите, количество сайтов постоянно, но я бы хотел столбец, в котором номер сайта сбрасывается с каждым блоком. Например, я хотел бы что-то вроде этого ниже:

block  site     day  X1   X2    site2
1      1        1    0.4  5.1   1
1      1        2    0.8  1.1   1
1      1        3    1.1  4.2   1
1      2        1    ...  ...   2
1      2        2               2
1      2        3               2
2      3        1               1
2      3        2               1
2      3        3               1
2      4        1               2
2      4        2               2
2      4        3               2

Я думал об использовании функции Rle, но не уверен, что она будет работать из-за сложностей с днем. В противном случае я бы попробовал что-то вроде:

Data$site2 <- sequence(rle(Data$block)$lengths)

У кого-нибудь есть предложения по добавлению столбцов, подсчитывающих (последовательность) количество сайтов в каждом блоке? Если это поможет, то для каждого сайта будет записано одинаковое количество дней (263), но количество блоков в каждом блоке будет разным.

Ответы [ 3 ]

6 голосов
/ 18 декабря 2011

Вот немного неуклюжее решение с использованием plyr и ddply:

ddply(df,.(block),transform,
                  site1 = rep(1:length(unique(site)),
                             times = rle(site)$lengths))

Или немного более гладкая версия:

ddply(df,.(block),transform,site1 = as.integer(as.factor(site)))

Может быть умныйхотя я могу сделать это напрямую, используя различные функции seq, sequence и rle, но мой мозг немного запутан в данный момент.Если вы оставите это открытым какое-то время, кто-то, скорее всего, придет с нехитрым, не plyr решением.

1 голос
/ 18 декабря 2011

Использование tapply может работать

# Make some fake data
dat <- data.frame(block = rep(1:3, each = 4), site = rep(1:6, each  = 2), val = rnorm(12))
# For each block reset the count
dat$site2 <- unlist(tapply(dat$site, dat$block, function(x){x - min(x) + 1}))
0 голосов
/ 18 декабря 2011

Через пр.:

df1 <- structure(list(block = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2), 
    site = c(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4), day = c(1, 
    2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)), .Names = c("block", "site", 
"day"), row.names = c("2", "3", "4", "5", "6", "7", "8", "9", 
"10", "11", "12", "13"), class = "data.frame")

df1$site2 <- ave(df1$site,df1$block,FUN=function(x) match(x,sort(unique(x))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...