Как исправить "замена имеет х строк, данные имеют г" в R - PullRequest
0 голосов
/ 13 апреля 2019

У меня есть этот набор данных, который включает в себя все продажи для компании в данном году (балансовая единица = gvkey, year = fyeqarq, sales = realsales).После расчета годовых темпов роста продаж, я пытаюсь вставить их в df.По какой-то причине я получаю следующее сообщение об ошибке «Ошибка в $<-.data.frame (*tmp*, growth_rate, value = c (10041 = NA,: замена имеет 204072 строк, данные имеют 204024» при этом.

Я уже пытался удалить все значения NA и другие решения, найденные на этом форуме, но, к сожалению, ни одно из них не сработало.

Фрагмент кода, который приводит к этой ошибке:

rs <- rs[order(rs$gvkey, rs$fyearq, rs$realsales),]


table(is.na(rs$realsales))


rs <- rs %>%

  group_by(gvkey) %>%
  filter(!any(is.na(realsales))) %>%
  ungroup()
rs$growth_rate <- NA

growth_rate <-function(x){
  out <- c(NA,  x[2:length(x)]/ x[1:(length(x)-1)])
  return(out)
}
rs$growth_rate <- do.call("c", by(rs$realsales,rs$gvkey, growth_rate))

Он создает значение со всеми 204072 элементами, если я только запускаю

growth_rate <- do.call("c", by(rs$realsales,rs$gvkey, growth_rate))

Я не знаю, указывает ли это на что-то, но думал, что стоит упомянуть.

Все работает, пока не достигнет последней строки.

Еще одна важная вещь, на которую следует обратить внимание: это не происходило с предыдущим набором данных. Я немного изменил его, чтобы иметь больше наблюдений, чем предыдущий, но этона самом деле то же самое, только больше. Только сейчас я получаю эту ошибку. Одно отличие состоит в том, что я объединил два фрейма данных, чтобы преобразовать номинальные продажи в реальные продажи, чего у меня нетсделано в предыдущем.Сегмент, где я делаю это:

df.gdpdeflator <- read.table("gdpdeflator.txt", header=TRUE)

real_sales <- left_join(sumofsalesbyfirm, df.gdpdeflator, by = "fyearq")
real_sales$realsales <- real_sales$saley/(real_sales$deflator/100)
rs <- aggregate(realsales~gvkey+fyearq, real_sales, sum)

Дайте мне знать, если потребуется дополнительная информация, я буду рад предоставить ее.

1 Ответ

4 голосов
/ 13 апреля 2019

Использование 2:length(x) работает нормально, если ваш x имеет длину 2 или больше.Я полагаю, что ваше намерение состоит в том, чтобы получить все, кроме первого, и в этом случае все эти работы:

x <- 1:10
x[-1]
x[ seq_len(length(x))[-1] ]
tail(x, n=-1)
# [1]  2  3  4  5  6  7  8  9 10

Позвольте мне немного формализовать это, чтобы показать несколько вариантов (неправильных и правильных) и показать некоторые результаты.

allbutfirst <- function(n) {
  sapply(list(
    wrong1 = 2:length(n),
    wrong2 = n[ 2:length(n) ],
    right1 = n[ -1 ],
    right2 = n[ seq_len(length(n))[-1] ],
    right3 = tail(n, n=-1)
  ), paste, collapse = ",")
}

allbutlast <- function(m) {
  sapply(list(
    wrong1 = 1:(length(m)-1),
    wrong2 = m[ 1:max(0, length(m)-1) ],
    right1 = m[ -length(m) ],
    right2 = m[ seq_len(max(0, length(m) - 1)) ],
    right3 = head(m, n=-1)
  ), paste, collapse = ",")
}
allbutfirst(1:5)
#    wrong1    wrong2    right1    right2    right3 
# "2,3,4,5" "2,3,4,5" "2,3,4,5" "2,3,4,5" "2,3,4,5" 
cat(paste(allbutfirst(1:5), collapse = "\n"))
# 2,3,4,5
# 2,3,4,5
# 2,3,4,5
# 2,3,4,5
# 2,3,4,5
cat(paste(allbutfirst(1), collapse = "\n"))
# 2,1
# NA,1
# 
# 
# 

(метки wrong присутствуют, потому что они ошибаются, когда длина не равна 2 и более ...)

"2,3,4,5" означает, что возвращаемый вектор имеет длинучетыре, итерация от 2 до 5. "2,1" означает длину два, уменьшив с 2 до 1 (когда мы не собирались это делать).Конечно, NA просто не прав.

Пустые строки там актуальны: они означают, что их было меньше 2, и ничего не было возвращено (что мы и хотим).Чтобы вызвать пустые строки, я заменю их на "", просто для галочки.Но они пусты, как и должно быть.

Так что эта «таблица» обозначает различные методы

                            allbutfirst(x)     allbutlast(x)

x <- 1:5         wrong1     2,3,4,5            1,2,3,4
                 wrong2     2,3,4,5            1,2,3,4
                 right1     2,3,4,5            1,2,3,4
                 right2     2,3,4,5            1,2,3,4
                 right3     2,3,4,5            1,2,3,4

Пока все хорошо, никакого вреда пока нет.

                            allbutfirst(x)     allbutlast(x)

x <- 1           wrong1     2,1                1,0            <-- length 2, expected none
                 wrong2     NA,1               1              <-- 2 or 1, expected 0
                 right1     ""                 ""   
                 right2     ""                 ""   
                 right3     ""                 ""

x <- integer(0)  wrong1     2,1,0              1,0,-1         <-- length 3? negative?
                 wrong2     NA,NA              NA             <-- all wrong
                 right1     ""                 ""
                 right2     ""                 ""
                 right3     ""                 ""

Мораль истории:

  • использование head и tail с отрицательный счет хорошо работает
  • использование x[-1] и x[-length(x)] эквивалентен и все еще хорошо работает
  • seq_len(max(0, ...)) - безопасный способ ведения дел;seq_len(0) всегда будет пустым, 1:0 не будет.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...